mirror of
https://github.com/napnap75/multiarch-docker-images.git
synced 2026-11-11 00:22:12 +01:00
feat(setup): add the standard created/updated autodate columns
Both collections are created programmatically, so PocketBase's default created/updated autodate fields were absent and the admin UI showed no creation/modification dates. Declared explicitly on documents (re-added each start like the other fixed columns, protected from the config cleanup) and on document_events at creation. The authoritative history remains document_events.
This commit is contained in:
+2
-1
@@ -49,12 +49,13 @@ One row per processed PDF file:
|
||||
- `file_key`: current S3 key of the file
|
||||
- `pages`: page-by-page extracted text as a JSON array (0-based, `pages[0]` = page 1); the FTS5 full-text index is built from the concatenation of all pages
|
||||
- `status`: `pending` | `processed` | `validated`
|
||||
- `created` / `updated`: the standard PocketBase autodate columns, added for convenience in the admin UI; the authoritative history remains `document_events`
|
||||
+ all the fields declared by the user in the configuration file
|
||||
|
||||
The append-only `document_events` collection is the single source of truth for a document's history; no history is stored on the `documents` record itself.
|
||||
|
||||
### `document_events`
|
||||
Append-only history: `document`, `event_type` (`imported`, `corrected`, `validated`), `payload` as JSON, `timestamp`.
|
||||
Append-only history: `document`, `event_type` (`imported`, `corrected`, `validated`), `payload` as JSON, `timestamp`, plus the standard `created`/`updated` autodate columns; the event's business timestamp is `timestamp`, mirrored in the payload.
|
||||
|
||||
The payload is self-contained: each event carries its own type, its own timestamp and the document state before and after, so a document's full history is reconstructed from this collection alone; the snapshots are stored as diffs — each `before`/`after` carries only the fields the event changes. All dates are RFC 3339; all S3 keys are complete, prefix included.
|
||||
|
||||
|
||||
@@ -33,16 +33,22 @@ func ensureDocuments(app core.App, cfg *config.Config) error {
|
||||
coll = core.NewBaseCollection("documents")
|
||||
}
|
||||
|
||||
// Fixed columns (re)declared on every start, ordering preserved.
|
||||
// Fixed columns (re)declared on every start, ordering preserved, plus
|
||||
// the standard PocketBase created/updated autodate columns for
|
||||
// convenience in the admin UI (US-03).
|
||||
coll.Fields.RemoveByName("sha256")
|
||||
coll.Fields.RemoveByName("file_key")
|
||||
coll.Fields.RemoveByName("pages")
|
||||
coll.Fields.RemoveByName("status")
|
||||
coll.Fields.RemoveByName("created")
|
||||
coll.Fields.RemoveByName("updated")
|
||||
coll.Fields.Add(
|
||||
&core.TextField{Name: "sha256"},
|
||||
&core.TextField{Name: "file_key"},
|
||||
&core.JSONField{Name: "pages"},
|
||||
&core.SelectField{Name: "status", MaxSelect: 1, Values: []string{"pending", "processed", "validated"}},
|
||||
&core.AutodateField{Name: "created", OnCreate: true},
|
||||
&core.AutodateField{Name: "updated", OnCreate: true, OnUpdate: true},
|
||||
)
|
||||
|
||||
// One column per declared field, mapped from the field type (US-03).
|
||||
@@ -95,7 +101,7 @@ func ensureDocuments(app core.App, cfg *config.Config) error {
|
||||
}
|
||||
|
||||
func isFixed(name string) bool {
|
||||
for _, f := range []string{"sha256", "file_key", "pages", "status"} {
|
||||
for _, f := range []string{"sha256", "file_key", "pages", "status", "created", "updated"} {
|
||||
if f == name {
|
||||
return true
|
||||
}
|
||||
@@ -117,6 +123,8 @@ func ensureEvents(app core.App) error {
|
||||
&core.SelectField{Name: "event_type", MaxSelect: 1, Values: []string{"imported", "corrected", "validated"}},
|
||||
&core.JSONField{Name: "payload"},
|
||||
&core.DateField{Name: "timestamp"},
|
||||
&core.AutodateField{Name: "created", OnCreate: true},
|
||||
&core.AutodateField{Name: "updated", OnCreate: true, OnUpdate: true},
|
||||
)
|
||||
// Append-only (US-04): API rules locked to superusers are not enough,
|
||||
// the standard admin UI uses a superuser; the request hooks in
|
||||
|
||||
@@ -39,7 +39,7 @@ so that the persistence schema always reflects the declared extraction fields.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Given the `documents` collection does not exist, when the application starts, then it is created with the fixed columns (`sha256` unique-indexed, `file_key`, `pages` as a JSON array, `status`) plus one column per field declared in `fields`.
|
||||
- Given the `documents` collection does not exist, when the application starts, then it is created with the fixed columns (`sha256` unique-indexed, `file_key`, `pages` as a JSON array, `status`), the standard PocketBase `created`/`updated` autodate columns, plus one column per field declared in `fields`.
|
||||
- Given a declared field, when its column is created, then the column type maps from the field type: `text`→text, `number`→number, `date`→date, `boolean`→bool, `enum`→select (single value).
|
||||
- Given the `documents` collection exists and a field was added to `config.jsonc`, when the application starts, then the matching column is added without data loss.
|
||||
- Given a field was removed from `config.jsonc`, when the application starts, then the matching column is removed and the operation is logged; existing values in that column are lost by design (they remain in the event history snapshots).
|
||||
@@ -54,7 +54,7 @@ so that the history of a document remains an immutable, append-only source of tr
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Given the `document_events` collection does not exist, when the application starts, then it is created with the columns `document` (relation to `documents`, cascade delete with the record), `event_type` (select: `imported`, `corrected`, `validated`), `payload` (JSON), `timestamp` (date).
|
||||
- Given the `document_events` collection does not exist, when the application starts, then it is created with the columns `document` (relation to `documents`, cascade delete with the record), `event_type` (select: `imported`, `corrected`, `validated`), `payload` (JSON), `timestamp` (date), plus the standard PocketBase `created`/`updated` autodate columns.
|
||||
- Given the collection exists, when the application starts, then its schema is verified and left unchanged.
|
||||
- Given any API request that tries to update or delete a `document_events` record, when it is served, then it is rejected by the application's request hooks (`OnRecordUpdateRequest` / `OnRecordDeleteRequest` for the collection, bound to superusers as well). API rules alone cannot enforce this: superusers bypass all API rules, and no rule value blocks everyone (`null` = superusers only, empty string = public).
|
||||
- Given a record is appended, when the write succeeds, then it is never modified afterwards by the application itself.
|
||||
|
||||
Reference in New Issue
Block a user