@hollware/server 0.0.2 → 0.1.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.
@@ -0,0 +1,132 @@
1
+ CREATE TABLE `entries` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `site_id` text NOT NULL,
4
+ `collection` text NOT NULL,
5
+ `locale` text NOT NULL,
6
+ `slug` text NOT NULL,
7
+ `translation_group` text,
8
+ `status` text NOT NULL,
9
+ `version` integer NOT NULL,
10
+ `head_rev` text NOT NULL,
11
+ `published_rev` text,
12
+ `published_at` text,
13
+ `published_sort_key` text,
14
+ `scheduled_at` text,
15
+ `created_at` text NOT NULL,
16
+ `updated_at` text NOT NULL,
17
+ FOREIGN KEY (`site_id`) REFERENCES `sites`(`id`) ON UPDATE no action ON DELETE no action,
18
+ CONSTRAINT "entries_status" CHECK("entries"."status" IN ('draft', 'scheduled', 'published')),
19
+ CONSTRAINT "entries_version" CHECK("entries"."version" >= 1),
20
+ CONSTRAINT "entries_draft" CHECK("entries"."status" <> 'draft' OR ("entries"."published_rev" IS NULL AND "entries"."published_sort_key" IS NULL AND "entries"."scheduled_at" IS NULL)),
21
+ CONSTRAINT "entries_published" CHECK("entries"."status" <> 'published' OR ("entries"."published_rev" IS NOT NULL AND "entries"."published_at" IS NOT NULL AND "entries"."published_sort_key" IS NOT NULL)),
22
+ CONSTRAINT "entries_scheduled" CHECK("entries"."status" <> 'scheduled' OR "entries"."scheduled_at" IS NOT NULL)
23
+ );
24
+ --> statement-breakpoint
25
+ CREATE INDEX `entries_head` ON `entries` (`site_id`,`collection`,`updated_at`,`id`);--> statement-breakpoint
26
+ CREATE INDEX `entries_head_locale` ON `entries` (`site_id`,`collection`,`locale`,`updated_at`,`id`);--> statement-breakpoint
27
+ CREATE INDEX `entries_published` ON `entries` (`site_id`,`collection`,`locale`,`published_sort_key`,`id`) WHERE "entries"."status" = 'published';--> statement-breakpoint
28
+ CREATE UNIQUE INDEX `entries_id_site` ON `entries` (`id`,`site_id`);--> statement-breakpoint
29
+ CREATE UNIQUE INDEX `entries_slug` ON `entries` (`site_id`,`collection`,`locale`,`slug`);--> statement-breakpoint
30
+ CREATE UNIQUE INDEX `entries_translation` ON `entries` (`site_id`,`collection`,`translation_group`,`locale`);--> statement-breakpoint
31
+ CREATE TABLE `publications` (
32
+ `id` text PRIMARY KEY NOT NULL,
33
+ `site_id` text NOT NULL,
34
+ `entry_id` text NOT NULL,
35
+ `action` text NOT NULL,
36
+ `revision_id` text,
37
+ `verdict` text,
38
+ `acknowledged` text NOT NULL,
39
+ `actor_kind` text NOT NULL,
40
+ `actor_user_id` text NOT NULL,
41
+ `actor_token_id` text,
42
+ `actor_meta` text,
43
+ `created_at` text NOT NULL,
44
+ `updated_at` text NOT NULL,
45
+ FOREIGN KEY (`site_id`) REFERENCES `sites`(`id`) ON UPDATE no action ON DELETE no action,
46
+ FOREIGN KEY (`entry_id`,`site_id`) REFERENCES `entries`(`id`,`site_id`) ON UPDATE no action ON DELETE no action,
47
+ FOREIGN KEY (`revision_id`,`site_id`) REFERENCES `revisions`(`id`,`site_id`) ON UPDATE no action ON DELETE no action,
48
+ FOREIGN KEY (`actor_user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action,
49
+ FOREIGN KEY (`actor_token_id`,`site_id`) REFERENCES `tokens`(`id`,`site_id`) ON UPDATE no action ON DELETE no action,
50
+ CONSTRAINT "publications_action" CHECK("publications"."action" IN ('publish', 'unpublish')),
51
+ CONSTRAINT "publications_shape" CHECK(("publications"."action" = 'publish' AND "publications"."revision_id" IS NOT NULL AND "publications"."verdict" IS NOT NULL) OR ("publications"."action" = 'unpublish' AND "publications"."revision_id" IS NULL AND "publications"."verdict" IS NULL)),
52
+ CONSTRAINT "publications_actor_kind" CHECK("publications"."actor_kind" IN ('token', 'user', 'oauth_client')),
53
+ CONSTRAINT "publications_json" CHECK(json_valid("publications"."acknowledged") AND json_type("publications"."acknowledged") = 'array' AND ("publications"."verdict" IS NULL OR json_valid("publications"."verdict")) AND ("publications"."actor_meta" IS NULL OR json_valid("publications"."actor_meta")))
54
+ );
55
+ --> statement-breakpoint
56
+ CREATE INDEX `publications_entry` ON `publications` (`entry_id`,`created_at`);--> statement-breakpoint
57
+ CREATE UNIQUE INDEX `publications_id_site` ON `publications` (`id`,`site_id`);--> statement-breakpoint
58
+ CREATE TABLE `revision_tags` (
59
+ `id` text PRIMARY KEY NOT NULL,
60
+ `site_id` text NOT NULL,
61
+ `revision_id` text NOT NULL,
62
+ `tag` text NOT NULL,
63
+ `created_at` text NOT NULL,
64
+ `updated_at` text NOT NULL,
65
+ FOREIGN KEY (`site_id`) REFERENCES `sites`(`id`) ON UPDATE no action ON DELETE no action,
66
+ FOREIGN KEY (`revision_id`,`site_id`) REFERENCES `revisions`(`id`,`site_id`) ON UPDATE no action ON DELETE no action
67
+ );
68
+ --> statement-breakpoint
69
+ CREATE INDEX `revision_tags_by_tag` ON `revision_tags` (`site_id`,`tag`);--> statement-breakpoint
70
+ CREATE UNIQUE INDEX `revision_tags_id_site` ON `revision_tags` (`id`,`site_id`);--> statement-breakpoint
71
+ CREATE UNIQUE INDEX `revision_tags_tag` ON `revision_tags` (`revision_id`,`tag`);--> statement-breakpoint
72
+ CREATE TABLE `revisions` (
73
+ `id` text PRIMARY KEY NOT NULL,
74
+ `site_id` text NOT NULL,
75
+ `entry_id` text NOT NULL,
76
+ `markdown` text NOT NULL,
77
+ `frontmatter` text NOT NULL,
78
+ `document` text NOT NULL,
79
+ `comark_version` text NOT NULL,
80
+ `pipeline_version` text NOT NULL,
81
+ `word_count` integer NOT NULL,
82
+ `verdict` text NOT NULL,
83
+ `actor_kind` text NOT NULL,
84
+ `actor_user_id` text NOT NULL,
85
+ `actor_token_id` text,
86
+ `actor_meta` text,
87
+ `created_at` text NOT NULL,
88
+ `updated_at` text NOT NULL,
89
+ FOREIGN KEY (`site_id`) REFERENCES `sites`(`id`) ON UPDATE no action ON DELETE no action,
90
+ FOREIGN KEY (`entry_id`,`site_id`) REFERENCES `entries`(`id`,`site_id`) ON UPDATE no action ON DELETE no action,
91
+ FOREIGN KEY (`actor_user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action,
92
+ FOREIGN KEY (`actor_token_id`,`site_id`) REFERENCES `tokens`(`id`,`site_id`) ON UPDATE no action ON DELETE no action,
93
+ CONSTRAINT "revisions_actor_kind" CHECK("revisions"."actor_kind" IN ('token', 'user', 'oauth_client')),
94
+ CONSTRAINT "revisions_json" CHECK(json_valid("revisions"."frontmatter") AND json_valid("revisions"."document") AND json_valid("revisions"."verdict") AND ("revisions"."actor_meta" IS NULL OR json_valid("revisions"."actor_meta"))),
95
+ CONSTRAINT "revisions_word_count" CHECK("revisions"."word_count" >= 0)
96
+ );
97
+ --> statement-breakpoint
98
+ CREATE INDEX `revisions_entry` ON `revisions` (`entry_id`,`created_at`);--> statement-breakpoint
99
+ CREATE UNIQUE INDEX `revisions_id_site` ON `revisions` (`id`,`site_id`);--> statement-breakpoint
100
+ CREATE TABLE `sites` (
101
+ `id` text PRIMARY KEY NOT NULL,
102
+ `created_at` text NOT NULL,
103
+ `updated_at` text NOT NULL
104
+ );
105
+ --> statement-breakpoint
106
+ CREATE TABLE `tokens` (
107
+ `id` text PRIMARY KEY NOT NULL,
108
+ `site_id` text NOT NULL,
109
+ `user_id` text NOT NULL,
110
+ `label` text NOT NULL,
111
+ `hash` text NOT NULL,
112
+ `scopes` text NOT NULL,
113
+ `expires_at` text,
114
+ `revoked_at` text,
115
+ `last_used_at` text,
116
+ `created_at` text NOT NULL,
117
+ `updated_at` text NOT NULL,
118
+ FOREIGN KEY (`site_id`) REFERENCES `sites`(`id`) ON UPDATE no action ON DELETE no action,
119
+ FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action,
120
+ CONSTRAINT "tokens_scopes" CHECK(json_valid("tokens"."scopes") AND json_type("tokens"."scopes") = 'array')
121
+ );
122
+ --> statement-breakpoint
123
+ CREATE UNIQUE INDEX `tokens_id_site` ON `tokens` (`id`,`site_id`);--> statement-breakpoint
124
+ CREATE UNIQUE INDEX `tokens_hash` ON `tokens` (`hash`);--> statement-breakpoint
125
+ CREATE TABLE `users` (
126
+ `id` text PRIMARY KEY NOT NULL,
127
+ `name` text,
128
+ `role` text NOT NULL,
129
+ `created_at` text NOT NULL,
130
+ `updated_at` text NOT NULL,
131
+ CONSTRAINT "users_role" CHECK("users"."role" IN ('owner', 'editor', 'reviewer'))
132
+ );
@@ -0,0 +1,70 @@
1
+ -- Append-only tables (ADR-021): revisions, their tags and publications are written once.
2
+ -- Written by hand: drizzle-kit does not model triggers (it never drops them on `generate`), but a
3
+ -- later migration that rebuilds one of these tables drops its triggers with the old table, so it
4
+ -- must create them again. The test append-only.workerd.test.ts lists them after every migration.
5
+ --
6
+ -- Three triggers per table:
7
+ -- *_no_delete a row is never deleted;
8
+ -- *_immutable the columns that make a row what it is never change; only the columns
9
+ -- `hollware reparse` derives again may (and `updated_at`);
10
+ -- *_no_replace an INSERT whose unique key is taken aborts. INSERT OR REPLACE deletes the
11
+ -- row it replaces without firing DELETE triggers (recursive_triggers is off),
12
+ -- so without it a revision could be overwritten.
13
+ -- Every message starts with "append-only:", which is what the repository code matches.
14
+
15
+ CREATE TRIGGER `revisions_no_delete`
16
+ BEFORE DELETE ON `revisions`
17
+ BEGIN
18
+ SELECT RAISE(ABORT, 'append-only: a revision is never deleted');
19
+ END;
20
+ --> statement-breakpoint
21
+ CREATE TRIGGER `revisions_immutable`
22
+ BEFORE UPDATE OF `id`, `site_id`, `entry_id`, `markdown`, `verdict`, `actor_kind`, `actor_user_id`, `actor_token_id`, `actor_meta`, `created_at` ON `revisions`
23
+ BEGIN
24
+ SELECT RAISE(ABORT, 'append-only: only the derived columns of a revision change');
25
+ END;
26
+ --> statement-breakpoint
27
+ CREATE TRIGGER `revisions_no_replace`
28
+ BEFORE INSERT ON `revisions`
29
+ WHEN EXISTS (SELECT 1 FROM `revisions` WHERE `id` = NEW.`id`)
30
+ BEGIN
31
+ SELECT RAISE(ABORT, 'append-only: a revision with this id already exists');
32
+ END;
33
+ --> statement-breakpoint
34
+ CREATE TRIGGER `revision_tags_no_delete`
35
+ BEFORE DELETE ON `revision_tags`
36
+ BEGIN
37
+ SELECT RAISE(ABORT, 'append-only: a revision tag is never deleted');
38
+ END;
39
+ --> statement-breakpoint
40
+ CREATE TRIGGER `revision_tags_immutable`
41
+ BEFORE UPDATE OF `id`, `site_id`, `revision_id`, `tag`, `created_at` ON `revision_tags`
42
+ BEGIN
43
+ SELECT RAISE(ABORT, 'append-only: a revision tag never changes');
44
+ END;
45
+ --> statement-breakpoint
46
+ CREATE TRIGGER `revision_tags_no_replace`
47
+ BEFORE INSERT ON `revision_tags`
48
+ WHEN EXISTS (SELECT 1 FROM `revision_tags` WHERE `id` = NEW.`id` OR (`revision_id` = NEW.`revision_id` AND `tag` = NEW.`tag`))
49
+ BEGIN
50
+ SELECT RAISE(ABORT, 'append-only: this revision already has this tag');
51
+ END;
52
+ --> statement-breakpoint
53
+ CREATE TRIGGER `publications_no_delete`
54
+ BEFORE DELETE ON `publications`
55
+ BEGIN
56
+ SELECT RAISE(ABORT, 'append-only: a publication is never deleted');
57
+ END;
58
+ --> statement-breakpoint
59
+ CREATE TRIGGER `publications_immutable`
60
+ BEFORE UPDATE OF `id`, `site_id`, `entry_id`, `action`, `revision_id`, `verdict`, `acknowledged`, `actor_kind`, `actor_user_id`, `actor_token_id`, `actor_meta`, `created_at` ON `publications`
61
+ BEGIN
62
+ SELECT RAISE(ABORT, 'append-only: a publication never changes');
63
+ END;
64
+ --> statement-breakpoint
65
+ CREATE TRIGGER `publications_no_replace`
66
+ BEFORE INSERT ON `publications`
67
+ WHEN EXISTS (SELECT 1 FROM `publications` WHERE `id` = NEW.`id`)
68
+ BEGIN
69
+ SELECT RAISE(ABORT, 'append-only: a publication with this id already exists');
70
+ END;
@@ -0,0 +1,42 @@
1
+ {
2
+ "version": "6",
3
+ "dialect": "sqlite",
4
+ "id": "9656842a-65d5-4c81-839f-a07315744088",
5
+ "prevId": "00000000-0000-0000-0000-000000000000",
6
+ "tables": {
7
+ "_hollware_meta": {
8
+ "name": "_hollware_meta",
9
+ "columns": {
10
+ "key": {
11
+ "name": "key",
12
+ "type": "text",
13
+ "primaryKey": true,
14
+ "notNull": true,
15
+ "autoincrement": false
16
+ },
17
+ "value": {
18
+ "name": "value",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true,
22
+ "autoincrement": false
23
+ }
24
+ },
25
+ "indexes": {},
26
+ "foreignKeys": {},
27
+ "compositePrimaryKeys": {},
28
+ "uniqueConstraints": {},
29
+ "checkConstraints": {}
30
+ }
31
+ },
32
+ "views": {},
33
+ "enums": {},
34
+ "_meta": {
35
+ "schemas": {},
36
+ "tables": {},
37
+ "columns": {}
38
+ },
39
+ "internal": {
40
+ "indexes": {}
41
+ }
42
+ }