Build Your First SignalDesk AI Schema
Your first SignalDesk schema will store organizations, customers, tickets, and messages with explicit keys, constraints, and relationships. The goal is not merely to create four tables. It is to make invalid ownership, status, priority, and authorship states difficult or impossible while keeping every seed operation reproducible and verifiable.
What will you be able to do?
- Translate simple business rules into PostgreSQL DDL.
- Use identity keys, NOT NULL, CHECK, UNIQUE, and foreign keys.
- Insert related rows in one transaction.
- Read constraint errors as evidence of protected invariants.
Prerequisites
Connect to signaldesk_learning. Confirm the database and the signaldesk schema from the previous chapter.
What is the mental model?
A table is an API for facts. Columns are inputs, constraints are preconditions, and committed rows are accepted facts. The database is the final shared referee because application code, scripts, imports, jobs, and future AI tools may all write data.
Rendering diagram...
Which business rules will the database enforce?
- An organization has a unique slug.
- A customer email is unique inside an organization, not globally.
- A ticket belongs to the same organization recorded with it.
- Status and priority come from explicit allowed sets.
- A message belongs to a ticket and has a known author kind.
- Instants use timestamptz and default to the transaction’s current time.
How do you create the schema?
Run this in the learning database:
The composite foreign keys are intentional: they prevent a ticket or message from pointing across organizations even if application code passes mismatched identifiers. The supporting unique constraints make the referenced column sets valid foreign-key targets.
How do you seed related data atomically?
RETURNING carries generated identities through the statement without guessing sequence values.
Prove it worked
Then intentionally test one invariant inside a rollbackable transaction:
The statement must fail with tickets_status_allowed. The transaction will be aborted until ROLLBACK; that behavior is important.
Why does this matter in AI-native systems?
A classifier may suggest an unknown priority, a tool call may carry a ticket from another tenant, and a summarizer may return blank output. Constraints turn those mistakes into visible failures before corrupted facts are committed. AI can propose; the database still enforces the allowed state space.
Production judgment
- Text CHECK constraints are transparent for a small stable set; lookup tables or enums have different migration tradeoffs.
- Case-insensitive email identity needs a deliberate normalization policy; the simplified check here is not full email validation.
- ON DELETE CASCADE is appropriate for dependent messages only if the product truly permits ticket deletion. Regulated systems may retain or pseudonymize instead.
- now() is transaction-stable. updated_at does not update automatically; later chapters design explicit change behavior.
- Schema creation should run through versioned migrations, not ad hoc production sessions.
Common mistakes
AI Pair-Programmer Prompt
Hands-on exercise
Add an optional resolved_at timestamptz and enforce that resolved or closed tickets have a resolution time while open or pending tickets do not. Decide whether one constraint or two communicates the rule better.
Acceptance criterion: four negative tests reject every invalid status/time combination, and valid open and resolved rows insert inside a transaction you roll back.
Knowledge check
- Why use a composite tenant foreign key?
- What does RETURNING solve?
- Does DEFAULT now() update updated_at on later changes?
- What must happen after a statement error aborts a transaction?
Answers
- It proves the referenced child belongs to the same tenant as the parent row.
- It returns values, including generated identities, from changed rows without guessing.
- No. A default applies when the row is inserted unless a value is supplied.
- Issue ROLLBACK or roll back to an earlier savepoint before continuing.
Completion checklist
Primary references