1.8 KiB
1.8 KiB
Custom content types
A content type is a named schema (a key, a name and 1 to 50 fields) stored as one row with the fields as a JSON text column. Entries of every type share one generic table whose data column holds a JSON object. No DDL runs at runtime, so creating or changing a type never alters the database schema.
Layering
The domain packages internal/domain/contenttype and internal/domain/entry own the rules: key, name and field validation, entry validation against a schema, the sort whitelist, the page limits and the value equality used by uniqueness. The use cases orchestrate them through the two repositories. The repositories only store and load rows. Entry counting for the "type still has entries" rule lives on the entry repository.
Known limitations of phase 1
- Uniqueness and schema re-validation are O(n). Checking a unique field loads every entry of the type and compares values in Go, and updating a type with stored entries loads all of them to re-validate. This keeps the SQL portable across SQLite, MySQL/MariaDB and PostgreSQL. The path to fix it is the filterable-fields phase: project the values of unique and filterable fields into an indexed table, so uniqueness becomes an indexed lookup and re-validation can be restricted to the changed fields.
- Unique values are checked without a transaction, so two concurrent writes of the same unique value can both succeed. A content type key is protected by a unique index, and a violation is reported as
content_type_key_taken(409). entry.Repository.DeleteByContentTypeis intentionally unused for now. A content type that still has entries cannot be deleted; the method is kept as part of the repository contract for a later cascade.- Listing is limited to page 1,000,000 and to page sizes of 100 so that the SQL offset cannot overflow.