BUILD STUDIO / DATA ENGINEERING
Stockroom
Integrity before interface
Design a small synthetic business database, break a transaction deliberately, and prove that a foreign principal cannot write through the teaching adapter.
Browser checks execute your schema, migrations and queries in real SQLite. They do not execute src/store.mjs, implement PostgreSQL RLS or authenticate anyone. The downloaded Node suite executes the transaction/authority adapter. A separate optional package runs real PostgreSQL.
Opening your workspace…
The small project source is loaded only when this workspace opens.
Original project brief and legacy stage notes
Cross-academy build · 5 substantial stages
Build a synthetic mini ERP
Create a small customer, item, invoice, payment and stock workflow. Follow one operation from a typed form to an authorized atomic database change, using entirely invented business rules.
This is a project brief and local evidence notebook. Implement the project in your own development repository using synthetic data. Checklists and the review question record self-review; LearnLab does not execute these project files, inspect a live database, grade the implementation or certify security. Starter snippets are deliberately partial. Link actual commands, outputs, revisions and screenshots to your notes. Publishing requires a separate deliberate release decision.
Skills this project brings together
- A type is a promise; a boundary needs evidence
- Make failure part of the API contract
- Design away impossible states
- A form is state, semantics and feedback
- Choose one owner for each fact
- Make impossible relationships unrepresentable
- Make a change an all-or-nothing unit
- Reason about two writers, not one happy path
- Check the row before and after a change
- An RPC is an exposed function, not a permission shortcut
- Choose the test that can actually prove the claim
Implementation stage · self-review
1. Define the toy business contract
Write the allowed states and invariants before implementing screens. An invoice begins as draft, becomes issued once, and becomes paid when successful payments equal its total. For this exercise only, totals are quantity × unit integer cents with no tax, discounts, currencies or statutory rules. Issuing consumes stock exactly once; paying must not consume it again.
Acceptance criteria
Mark an item only after you have reviewed the corresponding implementation and evidence. These are your declarations, not automated test results.
Concrete tests to run
- A synthetic Lamp costs 2500 cents; quantity 2 produces exactly 5000 cents.
- Quantity 0, negative quantity, fractional quantity and unsafe-integer multiplication are rejected.
- A draft invoice cannot be paid; an issued 5000-cent invoice with no payment remains issued.
- A 5000-cent payment completes that invoice; a further positive payment is rejected under the toy no-overpayment contract.
If a React component and an API calculate different totals, identify the shared rule and trusted persistence authority before adding more formulas.
Open the partial starter
type InvoiceState = 'draft' | 'issued' | 'paid';
type Line = { itemId: string; quantity: number; unitCents: number };
type Invoice = { id: string; companyId: string; state: InvoiceState; lines: Line[] };
// First write independent examples of valid and rejected transitions.This fragment frames the next design decision. It is not a finished implementation.
Your evidence notebook
This notebook stores text and review declarations. It does not execute files, grade a capstone, grant mastery, or publish an application. Up to 50 recent learning drafts are retained; export a backup for longer-term work.