@harperfast/template-vanilla-studio 1.5.27 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/harper-best-practices/AGENTS.md +97 -3
- package/.agents/skills/harper-best-practices/SKILL.md +2 -0
- package/.agents/skills/harper-best-practices/rules/logging.md +92 -0
- package/.agents/skills/harper-best-practices/rules/programmatic-table-requests.md +4 -0
- package/.agents/skills/harper-best-practices/rules/schema-design-tooling.md +8 -3
- package/package.json +1 -1
- package/skills-lock.json +1 -1
|
@@ -29,6 +29,7 @@ Guidelines for building scalable, secure, and performant applications on Harper.
|
|
|
29
29
|
- 4.2 [Creating a Fabric Account and Cluster](#42-creating-a-fabric-account-and-cluster)
|
|
30
30
|
- 4.3 [Deploying to Harper Fabric](#43-deploying-to-harper-fabric)
|
|
31
31
|
- 4.4 [Serving Web Content](#44-serving-web-content)
|
|
32
|
+
- 4.5 [Logging Best Practices](#45-logging-best-practices)
|
|
32
33
|
|
|
33
34
|
---
|
|
34
35
|
|
|
@@ -71,19 +72,23 @@ Harper uses GraphQL schemas to define database tables, relationships, and APIs.
|
|
|
71
72
|
Harper extends GraphQL with custom directives that define database behavior. These are typically defined in `node_modules/harperdb/schema.graphql`. If you don't have access to that file, here is a reference of the most important ones:
|
|
72
73
|
|
|
73
74
|
##### Table Definition
|
|
75
|
+
|
|
74
76
|
- `@table`: Marks a GraphQL type as a Harper database table.
|
|
75
77
|
- `@export`: Automatically generates REST and WebSocket APIs for the table.
|
|
76
78
|
- `@table(expiration: Int)`: Configures a time-to-expire for records in the table (useful for caching).
|
|
77
79
|
|
|
78
80
|
##### Attribute Constraints & Indexing
|
|
81
|
+
|
|
79
82
|
- `@primaryKey`: Specifies the unique identifier for the table.
|
|
80
83
|
- `@indexed`: Creates a standard index on the field for faster lookups.
|
|
81
84
|
- `@indexed(type: "HNSW", distance: "cosine" | "euclidean" | "dot")`: Creates a vector index for similarity search.
|
|
82
85
|
|
|
83
86
|
##### Relationships
|
|
87
|
+
|
|
84
88
|
- `@relationship(from: String)`: Defines a relationship to another table. `from` specifies the local field holding the foreign key.
|
|
85
89
|
|
|
86
90
|
##### Authentication & Authorization
|
|
91
|
+
|
|
87
92
|
- `@auth(role: String)`: Restricts access to a table or field based on user roles.
|
|
88
93
|
|
|
89
94
|
#### Configuring GraphQL Tooling
|
|
@@ -98,12 +103,13 @@ Create a file named `graphql.config.yml` in your project root with the following
|
|
|
98
103
|
|
|
99
104
|
```yaml
|
|
100
105
|
schema:
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
106
|
+
- 'node_modules/harperdb/schema.graphql'
|
|
107
|
+
- 'schema.graphql'
|
|
108
|
+
- 'schemas/*.graphql'
|
|
104
109
|
```
|
|
105
110
|
|
|
106
111
|
##### Why this is important:
|
|
112
|
+
|
|
107
113
|
1. **Shared Directives**: It includes `@table`, `@primaryKey`, etc., so they aren't marked as "unknown directives".
|
|
108
114
|
2. **Context for Agents**: When an agent reads your project, seeing this config helps it locate the core Harper definitions, leading to more accurate code generation.
|
|
109
115
|
3. **Consistency**: The `npm create harper@latest` command includes this by default. Manually adding it to existing projects ensures they follow the same standards.
|
|
@@ -495,3 +501,91 @@ Two ways to serve web content from a Harper application.
|
|
|
495
501
|
|
|
496
502
|
1. **Static Serving**: Serve HTML, CSS, and JS files directly. If using the Vite plugin for development, ensure Harper is running (e.g., `harperdb run .`) to allow for Hot Module Replacement (HMR).
|
|
497
503
|
2. **Dynamic Rendering**: Use custom resources to render content on the fly.
|
|
504
|
+
|
|
505
|
+
### 4.5 Logging Best Practices
|
|
506
|
+
|
|
507
|
+
Harper provides a robust logging system that captures standard output and offers a granular, tagged logging interface for both local and deployed environments.
|
|
508
|
+
|
|
509
|
+
#### Standard Console Logging
|
|
510
|
+
|
|
511
|
+
The simplest way to log in Harper is using standard JavaScript console methods. `console.log()`, `console.warn()`, `console.error()`, and `console.trace()` are automatically captured by Harper and can be viewed in the logs.
|
|
512
|
+
|
|
513
|
+
- `console.log(...)`: Captured as `stdout` level in Harper logs.
|
|
514
|
+
- `console.warn(...)`: Captured as `stderr` level in Harper logs.
|
|
515
|
+
- `console.error(...)`: Captured as `stderr` level in Harper logs.
|
|
516
|
+
- `console.trace(...)`: Captured as `stdout` level in Harper logs (includes stack trace).
|
|
517
|
+
|
|
518
|
+
#### Harper Logger
|
|
519
|
+
|
|
520
|
+
For more granularity and better organization, use Harper's built-in `logger`. You can use the global `logger` object or import it from the `harper` package.
|
|
521
|
+
|
|
522
|
+
##### Log Levels
|
|
523
|
+
|
|
524
|
+
The Harper `logger` supports the following levels (ordered by increasing severity):
|
|
525
|
+
|
|
526
|
+
- `trace`
|
|
527
|
+
- `debug`
|
|
528
|
+
- `info`
|
|
529
|
+
- `warn`
|
|
530
|
+
- `error`
|
|
531
|
+
- `fatal`
|
|
532
|
+
- `notify`
|
|
533
|
+
|
|
534
|
+
##### Usage
|
|
535
|
+
|
|
536
|
+
```typescript
|
|
537
|
+
import { logger, loggerWithTag } from 'harper';
|
|
538
|
+
|
|
539
|
+
// Basic logging
|
|
540
|
+
logger.info('Application started');
|
|
541
|
+
logger.error('An error occurred', error);
|
|
542
|
+
|
|
543
|
+
// Tagged logging for better filtering (Namespacing)
|
|
544
|
+
const authLogger = loggerWithTag('auth');
|
|
545
|
+
authLogger.debug('User login attempt', { userId: '123' });
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Using `loggerWithTag` is highly recommended for grouping related logs, making them much easier to filter and analyze in the Harper Studio or via the API.
|
|
549
|
+
|
|
550
|
+
#### Programmatic Log Retrieval
|
|
551
|
+
|
|
552
|
+
You can programmatically read logs from a deployed Harper instance using the `read_log` operation. This is useful for building custom monitoring tools or debugging dashboards.
|
|
553
|
+
|
|
554
|
+
##### `read_log` Operation
|
|
555
|
+
|
|
556
|
+
The `read_log` operation is a POST request to the Harper instance.
|
|
557
|
+
|
|
558
|
+
**Example Request:**
|
|
559
|
+
|
|
560
|
+
```json
|
|
561
|
+
{
|
|
562
|
+
"operation": "read_log",
|
|
563
|
+
"limit": 100,
|
|
564
|
+
"start": 0,
|
|
565
|
+
"level": "error",
|
|
566
|
+
"order": "desc",
|
|
567
|
+
"from": "2024-01-01T00:00:00.000Z",
|
|
568
|
+
"until": "2024-01-02T00:00:00.000Z"
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
##### Parameters
|
|
573
|
+
|
|
574
|
+
- `limit`: Number of log entries to return.
|
|
575
|
+
- `start`: Offset for pagination.
|
|
576
|
+
- `level`: Filter by log level (`info`, `error`, `warn`, `debug`, `trace`, `notify`, `fatal`, `stdout`, `stderr`).
|
|
577
|
+
- `from`: ISO 8601 timestamp to start reading from.
|
|
578
|
+
- `until`: ISO 8601 timestamp to stop reading at.
|
|
579
|
+
- `order`: Sort order, either `asc` or `desc`.
|
|
580
|
+
- `replicated`: (Boolean) Include logs from replicated nodes in a cluster.
|
|
581
|
+
|
|
582
|
+
##### Log Entry Structure
|
|
583
|
+
|
|
584
|
+
Each log entry returned by `read_log` typically includes:
|
|
585
|
+
|
|
586
|
+
- `level`: The severity level of the log.
|
|
587
|
+
- `timestamp`: When the log was recorded.
|
|
588
|
+
- `thread`: The execution thread.
|
|
589
|
+
- `tags`: An array of tags (e.g., from `loggerWithTag`).
|
|
590
|
+
- `node`: The node name in a Harper cluster.
|
|
591
|
+
- `message`: The logged content.
|
|
@@ -79,6 +79,7 @@ See the concrete examples embedded in each rule subsection below (GraphQL schema
|
|
|
79
79
|
- `creating-a-fabric-account-and-cluster` - Setting up your Harper Fabric cloud infrastructure
|
|
80
80
|
- `creating-harper-apps` - Quickstart with `npm create harper@latest`
|
|
81
81
|
- `serving-web-content` - Ways to serve web content from Harper
|
|
82
|
+
- `logging` - Use standard console and Harper's granular logger
|
|
82
83
|
|
|
83
84
|
## How to Use
|
|
84
85
|
|
|
@@ -89,6 +90,7 @@ rules/adding-tables-with-schemas.md
|
|
|
89
90
|
rules/schema-design-tooling.md
|
|
90
91
|
rules/automatic-apis.md
|
|
91
92
|
rules/creating-harper-apps.md
|
|
93
|
+
rules/logging.md
|
|
92
94
|
```
|
|
93
95
|
|
|
94
96
|
## Full Compiled Document
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: logging
|
|
3
|
+
description: Best practices for logging in Harper, including console capture, the granular logger interface, and programmatic log retrieval.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Logging Best Practices
|
|
7
|
+
|
|
8
|
+
Harper provides a robust logging system that captures standard output and offers a granular, tagged logging interface for both local and deployed environments.
|
|
9
|
+
|
|
10
|
+
## Standard Console Logging
|
|
11
|
+
|
|
12
|
+
The simplest way to log in Harper is using standard JavaScript console methods. `console.log()`, `console.warn()`, `console.error()`, and `console.trace()` are automatically captured by Harper and can be viewed in the logs.
|
|
13
|
+
|
|
14
|
+
- `console.log(...)`: Captured as `stdout` level in Harper logs.
|
|
15
|
+
- `console.warn(...)`: Captured as `stderr` level in Harper logs.
|
|
16
|
+
- `console.error(...)`: Captured as `stderr` level in Harper logs.
|
|
17
|
+
- `console.trace(...)`: Captured as `stdout` level in Harper logs (includes stack trace).
|
|
18
|
+
|
|
19
|
+
## Harper Logger
|
|
20
|
+
|
|
21
|
+
For more granularity and better organization, use Harper's built-in `logger`. You can use the global `logger` object or import it from the `harper` package.
|
|
22
|
+
|
|
23
|
+
### Log Levels
|
|
24
|
+
|
|
25
|
+
The Harper `logger` supports the following levels (ordered by increasing severity):
|
|
26
|
+
|
|
27
|
+
- `trace`
|
|
28
|
+
- `debug`
|
|
29
|
+
- `info`
|
|
30
|
+
- `warn`
|
|
31
|
+
- `error`
|
|
32
|
+
- `fatal`
|
|
33
|
+
- `notify`
|
|
34
|
+
|
|
35
|
+
### Usage
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { logger, loggerWithTag } from 'harper';
|
|
39
|
+
|
|
40
|
+
// Basic logging
|
|
41
|
+
logger.info('Application started');
|
|
42
|
+
logger.error('An error occurred', error);
|
|
43
|
+
|
|
44
|
+
// Tagged logging for better filtering (Namespacing)
|
|
45
|
+
const authLogger = loggerWithTag('auth');
|
|
46
|
+
authLogger.debug('User login attempt', { userId: '123' });
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Using `loggerWithTag` is highly recommended for grouping related logs, making them much easier to filter and analyze in the Harper Studio or via the API.
|
|
50
|
+
|
|
51
|
+
## Programmatic Log Retrieval
|
|
52
|
+
|
|
53
|
+
You can programmatically read logs from a deployed Harper instance using the `read_log` operation. This is useful for building custom monitoring tools or debugging dashboards.
|
|
54
|
+
|
|
55
|
+
### `read_log` Operation
|
|
56
|
+
|
|
57
|
+
The `read_log` operation is a POST request to the Harper instance.
|
|
58
|
+
|
|
59
|
+
**Example Request:**
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"operation": "read_log",
|
|
64
|
+
"limit": 100,
|
|
65
|
+
"start": 0,
|
|
66
|
+
"level": "error",
|
|
67
|
+
"order": "desc",
|
|
68
|
+
"from": "2024-01-01T00:00:00.000Z",
|
|
69
|
+
"until": "2024-01-02T00:00:00.000Z"
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Parameters
|
|
74
|
+
|
|
75
|
+
- `limit`: Number of log entries to return.
|
|
76
|
+
- `start`: Offset for pagination.
|
|
77
|
+
- `level`: Filter by log level (`info`, `error`, `warn`, `debug`, `trace`, `notify`, `fatal`, `stdout`, `stderr`).
|
|
78
|
+
- `from`: ISO 8601 timestamp to start reading from.
|
|
79
|
+
- `until`: ISO 8601 timestamp to stop reading at.
|
|
80
|
+
- `order`: Sort order, either `asc` or `desc`.
|
|
81
|
+
- `replicated`: (Boolean) Include logs from replicated nodes in a cluster.
|
|
82
|
+
|
|
83
|
+
### Log Entry Structure
|
|
84
|
+
|
|
85
|
+
Each log entry returned by `read_log` typically includes:
|
|
86
|
+
|
|
87
|
+
- `level`: The severity level of the log.
|
|
88
|
+
- `timestamp`: When the log was recorded.
|
|
89
|
+
- `thread`: The execution thread.
|
|
90
|
+
- `tags`: An array of tags (e.g., from `loggerWithTag`).
|
|
91
|
+
- `node`: The node name in a Harper cluster.
|
|
92
|
+
- `message`: The logged content.
|
|
@@ -37,3 +37,7 @@ Use this skill when you need to perform database operations (CRUD, search, subsc
|
|
|
37
37
|
}
|
|
38
38
|
```
|
|
39
39
|
6. **Publish Events**: Use `publish(id, message)` to trigger subscriptions without necessarily persisting data.
|
|
40
|
+
|
|
41
|
+
## Cautions
|
|
42
|
+
|
|
43
|
+
Be very careful when performing updates and deletions! You may be dealing with live production data. The wrong request to delete, without approval from a human, could be devastating to a business. Always use the proper approval process.
|
|
@@ -12,19 +12,23 @@ Harper uses GraphQL schemas to define database tables, relationships, and APIs.
|
|
|
12
12
|
Harper extends GraphQL with custom directives that define database behavior. These are typically defined in `node_modules/harperdb/schema.graphql`. If you don't have access to that file, here is a reference of the most important ones:
|
|
13
13
|
|
|
14
14
|
### Table Definition
|
|
15
|
+
|
|
15
16
|
- `@table`: Marks a GraphQL type as a Harper database table.
|
|
16
17
|
- `@export`: Automatically generates REST and WebSocket APIs for the table.
|
|
17
18
|
- `@table(expiration: Int)`: Configures a time-to-expire for records in the table (useful for caching).
|
|
18
19
|
|
|
19
20
|
### Attribute Constraints & Indexing
|
|
21
|
+
|
|
20
22
|
- `@primaryKey`: Specifies the unique identifier for the table.
|
|
21
23
|
- `@indexed`: Creates a standard index on the field for faster lookups.
|
|
22
24
|
- `@indexed(type: "HNSW", distance: "cosine" | "euclidean" | "dot")`: Creates a vector index for similarity search.
|
|
23
25
|
|
|
24
26
|
### Relationships
|
|
27
|
+
|
|
25
28
|
- `@relationship(from: String)`: Defines a relationship to another table. `from` specifies the local field holding the foreign key.
|
|
26
29
|
|
|
27
30
|
### Authentication & Authorization
|
|
31
|
+
|
|
28
32
|
- `@auth(role: String)`: Restricts access to a table or field based on user roles.
|
|
29
33
|
|
|
30
34
|
## Configuring GraphQL Tooling
|
|
@@ -39,12 +43,13 @@ Create a file named `graphql.config.yml` in your project root with the following
|
|
|
39
43
|
|
|
40
44
|
```yaml
|
|
41
45
|
schema:
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
46
|
+
- 'node_modules/harperdb/schema.graphql'
|
|
47
|
+
- 'schema.graphql'
|
|
48
|
+
- 'schemas/*.graphql'
|
|
45
49
|
```
|
|
46
50
|
|
|
47
51
|
### Why this is important:
|
|
52
|
+
|
|
48
53
|
1. **Shared Directives**: It includes `@table`, `@primaryKey`, etc., so they aren't marked as "unknown directives".
|
|
49
54
|
2. **Context for Agents**: When an agent reads your project, seeing this config helps it locate the core Harper definitions, leading to more accurate code generation.
|
|
50
55
|
3. **Consistency**: The `npm create harper@latest` command includes this by default. Manually adding it to existing projects ensures they follow the same standards.
|
package/package.json
CHANGED
package/skills-lock.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"source": "harperfast/skills",
|
|
6
6
|
"sourceType": "github",
|
|
7
7
|
"skillPath": "harper-best-practices/SKILL.md",
|
|
8
|
-
"computedHash": "
|
|
8
|
+
"computedHash": "5ba34805d61ba1a997deffcbba9dd92ca775f286c4e8de8df0966518ff7b9eaf"
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
}
|