Commit Graph

46 Commits

Author SHA1 Message Date
c6a87e35d4 feat: complete CLI, Docker & deployment docs (Step 10.3)
- Add comprehensive CLI tests for seed and serve commands
- Create README.md with development setup, deployment guide,
  and environment variable reference
- Mark Step 10.3 as complete in PLAN.md

This completes the final implementation step.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 18:21:14 +00:00
229842fb45 feat: implement location events & error handling (Step 10.2)
- Add LocationService with create/rename/archive methods
- Add LocationProjection for event handling
- Add admin-only location management routes at /locations
- Add error response helpers (error_response, error_toast, success_toast)
- Add toast handler JS to base template for HX-Trigger notifications
- Update seeds.py to emit LocationCreated events per spec §23
- Archived locations block animal moves with 422 error

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 17:48:16 +00:00
5ba068b36a feat: implement E2E tests #1-5 (Step 10.1)
Add comprehensive E2E acceptance tests for stats progression:
- Test #1: Baseline eggs/feed/costs with 13 ducks
- Test #2: Mixed group proration with juveniles
- Test #3: Split flock per-location stats
- Test #4: Backdated eggs use historical roster
- Test #5: Event edit with revision tracking

Tests use cumulative fixtures building on each other.
Note: Some cost_per_egg_layers values differ from spec due to
integer bird-day truncation in implementation vs fractional
in spec calculations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 15:03:39 +00:00
719d1e6ce7 feat: implement user defaults persistence (Step 9.3)
Add user_defaults table and repository for persisting form defaults
across sessions. Feed and egg forms now load/save user preferences.

Changes:
- Add migration 0009-user-defaults.sql with table schema
- Add UserDefault model and UserDefaultsRepository
- Integrate defaults into feed route (location, feed_type, amount)
- Integrate defaults into egg route (location)
- Add repository unit tests and route integration tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 14:35:27 +00:00
0eef3ed7cb feat: implement product-sold route (Step 9.2)
Add POST /actions/product-sold route for recording product sales.

Changes:
- Create web/templates/products.py with product_sold_form
- Create web/routes/products.py with GET /sell and POST /actions/product-sold
- Wire up routes in __init__.py and app.py
- Add "Record Sale" link to Egg Quick Capture page
- Add comprehensive tests for form rendering and sale recording

The form allows selling any sellable product with quantity and price,
and calculates unit_price_cents using floor division. Defaults to
egg.duck product as per spec.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 14:16:12 +00:00
29ea3e27cb feat: complete Step 9.1 with outcome, status-correct, and quick actions
- Add animal-outcome route with yield items section for harvest products
- Add animal-status-correct route with @require_role(ADMIN) decorator
- Add exception handlers for AuthenticationError (401) and AuthorizationError (403)
- Enable quick action buttons in animal detail page (Add Tag, Promote, Record Outcome)
- Add comprehensive tests for outcome and status-correct routes (81 total action tests)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 13:45:06 +00:00
3acb731a6c feat: implement animal-tag-add and animal-tag-end routes (Step 9.1)
Add selection-based tag actions with optimistic locking:
- GET /actions/tag-add and POST /actions/animal-tag-add
- GET /actions/tag-end and POST /actions/animal-tag-end
- Form templates with selection preview and tag input/dropdown
- Diff panel for handling selection mismatches (409 response)
- Add TagProjection to the action service registry
- 16 tests covering form rendering, success, validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 12:50:38 +00:00
99f2fbb964 feat: add Promote Animal action route (Step 9.1 continued)
- Add /actions/promote/{animal_id} GET and /actions/animal-promote POST routes
- Add promote_form() template with nickname, sex, repro_status fields
- Add AnimalRepository.get() method for single-animal lookup
- 10 new tests for promote form rendering and submission

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 09:41:17 +00:00
f9e89fe5d6 feat: implement Cohort and Hatch action routes (Step 9.1 partial)
- Add /actions/cohort GET and /actions/animal-cohort POST routes
- Add /actions/hatch GET and /actions/hatch-recorded POST routes
- Add cohort_form() and hatch_form() templates
- Add Cohort and Hatch icons and navigation items
- Add list_active() method to SpeciesRepository
- Register action routes in app.py
- 26 new tests for cohort and hatch actions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 08:41:48 +00:00
301b925be3 feat: implement Animal Detail page with timeline (Step 8.3)
Add GET /animals/{animal_id} route to display individual animal details:
- Header summary with species, location, status, tags
- Event timeline showing all events affecting the animal (newest first)
- Quick actions card (Move functional, others disabled for now)
- Merge info alert for animals that have been merged

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 20:14:12 +00:00
bce4d099c9 feat: implement Event Log Projection & View (Step 8.2)
- Add migration 0008 for event_log_by_location table with cap trigger
- Create EventLogProjection for location-scoped event summaries
- Add GET /event-log route with location_id filtering
- Create event log templates with timeline styling
- Register EventLogProjection in eggs, feed, and move routes
- Cap events at 500 per location (trigger removes oldest)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 15:15:06 +00:00
8e155080e4 feat: implement Animal Registry view with filtering and pagination (Step 8.1)
- Add status field to filter DSL parser and resolver
- Create AnimalRepository with list_animals and get_facet_counts
- Implement registry templates with table, facet sidebar, infinite scroll
- Create registry route handler with HTMX partial support
- Default shows only alive animals; status filter overrides

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 14:59:13 +00:00
ff4fa86beb feat: implement Move Animals UI with optimistic locking (Step 7.5)
Add Move Animals form with selection context validation and concurrent
change handling via optimistic locking. When selection changes between
client resolution and submit, the user is shown a diff panel and can
confirm to proceed with the current server resolution.

Key changes:
- Add move template with form and diff panel components
- Add move routes (GET /move, POST /actions/animal-move)
- Register move routes in app
- Fix to_xml() usage for HTMLResponse (was using str())
- Use max(current_time, form_ts) for confirmed re-resolution

Tests:
- 15 route tests covering form rendering, success, validation, mismatch
- 7 E2E tests for optimistic lock flow (spec §21.8)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 14:31:03 +00:00
68e1a59ec7 feat: implement Feed Quick Capture form (Step 7.4)
Add /feed page with tabbed forms for Give Feed and Purchase Feed:
- GET /feed renders page with tabs (Give Feed default, Purchase Feed)
- POST /actions/feed-given records feed given to a location
- POST /actions/feed-purchased records feed purchases to inventory

Also adopts idiomatic FastHTML/HTMX pattern:
- Add hx-boost to base template for automatic AJAX on forms
- Refactor egg form to use action/method instead of hx_post

Spec §22 compliance:
- Integer kg only, min=1
- Warn if inventory negative (but allow)
- Toast + stay on page after submit
- Location/type stick, amount resets to default bag size

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 10:43:28 +00:00
e9804cdac8 feat: implement Egg Quick Capture form (Step 7.3)
Add the Egg Quick Capture functionality at GET / with POST /actions/product-collected.

Changes:
- Add list_active() to LocationRepository for active locations only
- Create web/templates/eggs.py with MonsterUI form components
- Create web/routes/eggs.py with GET and POST handlers
- Add CSRF bypass in dev_mode for easier development/testing
- Resolve ducks at location server-side for egg collection
- UX: location sticks after submit, quantity clears

Tests: 9 new tests covering form rendering and submission

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 21:17:18 +00:00
6cdf48fc32 feat: add health endpoints, static serving, and base template (Step 7.2)
- Add /healthz endpoint with DB writable check
- Add /metrics endpoint with Prometheus-compatible format (enabled by default)
- Configure static file serving at /static/v1/... with immutable cache headers
- Create base page template with MonsterUI slate theme
- Create industrial farm aesthetic bottom navigation with custom SVG icons
- Add StaticCacheMiddleware for adding cache-control headers

Changes:
- src/animaltrack/web/routes/health.py: Health and metrics endpoints
- src/animaltrack/web/templates/: Base template, nav, and icons
- src/animaltrack/web/app.py: Integrate theme, routes, static serving
- src/animaltrack/config.py: metrics_enabled defaults to True

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 20:35:57 +00:00
84225d865f feat: implement FastHTML app shell with auth/CSRF middleware (Step 7.1)
Add web layer foundation:
- FastHTML app factory with Beforeware pattern
- Auth middleware validating trusted proxy IPs and X-Oidc-Username header
- CSRF dual-token validation (cookie + header + Origin/Referer)
- Request ID generation (ULID) and NDJSON request logging
- Role-based permission helpers (can_edit_event, can_delete_event)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 19:52:15 +00:00
1153f6c5b6 feat: implement animal lifecycle events (Step 6.3)
Add 5 animal lifecycle event handlers with TDD:
- HatchRecorded: Creates hatchling animals at brood/event location
- AnimalOutcome: Records death/harvest/sold with yields, status updates
- AnimalPromoted: Sets identified flag, nickname, optionally updates sex/repro_status
- AnimalMerged: Merges animal records, creates aliases, removes merged from live roster
- AnimalStatusCorrected: Admin-only status correction with required reason

All events include:
- Projection handlers in animal_registry.py and intervals.py
- Event-animal linking in event_animals.py
- Service methods with validation in animal.py
- 51 unit tests covering event creation, projections, and validation
- E2E test #7 (harvest with yields) per spec §21.7

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 19:20:33 +00:00
282d3d0f5a feat: add event deletion with tombstone creation and cascade rules
Implement event deletion per spec §10 with role-based rules:
- Recorder can delete own events if no dependents exist
- Admin can cascade delete (tombstone target + all dependents)
- All deletions create immutable tombstone records

New modules:
- events/dependencies.py: find events depending on a target via shared animals
- events/delete.py: delete_event() with projection reversal

DependentEventsError exception added for 409 Conflict responses.
E2E test #6 implemented per spec §21.6.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 18:44:13 +00:00
f733a067e2 feat: add event editing with revision storage
Implements Step 6.1 of the plan:
- Add edit_event() function in events/edit.py
- Store old version in event_revisions before editing
- Increment version on edit
- Update projections via revert/apply pattern
- Add EventNotFoundError and EventTombstonedError exceptions

Tested with:
- Unit tests for revision storage and version increment
- Fast-revert tests for FeedGiven/FeedPurchased events
- Unbounded replay tests for AnimalMoved events
- E2E test #5: Edit egg event 8→6 with stats verification

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 16:03:17 +00:00
e9d3f34994 feat: add selection validation with optimistic locking
Implements Step 5.3 - selection validation for optimistic locking:

- SelectionContext: holds client's filter, resolved_ids, roster_hash, ts_utc
- SelectionDiff: shows added/removed animals on mismatch
- SelectionValidationResult: validation result with diff if applicable
- validate_selection(): re-resolves at ts_utc, compares hashes, returns diff
- SelectionMismatchError: exception for unconfirmed mismatches

Tests cover: hash match, mismatch detection, diff correctness, confirmed bypass,
from_location_id in hash comparison.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 15:46:19 +00:00
c80d9f7fda feat: add historical state resolver with point-in-time queries
Implement resolve_filter() to resolve animals matching FilterAST at ts_utc.
Uses interval tables for historical location, sex, life_stage, and tags.
Includes roster hash computation using xxhash64.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 15:31:07 +00:00
6e9fd17327 feat: add selection filter DSL parser
Implement parser for filter strings like "species:duck sex:female -tag:old".
Supports AND (space), OR (|), negation (-), and quoted values.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 15:19:11 +00:00
b48fab5dde feat: add product sold event handling
Add sell_product() service method that creates ProductSold events
with calculated unit_price_cents (floor division of total/qty).
Update ProductsProjection to handle PRODUCT_SOLD events.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 09:40:34 +00:00
c08fa476e0 feat: add 30-day egg stats computation service
Implement compute-on-read egg statistics per spec section 9:
- Create egg_stats_30d_by_location table (migration 0007)
- Add get_egg_stats service with bird-days calculation
- Calculate layer-eligible days (adult female + matching species)
- Implement feed proration formula with INTEGER truncation
- Cache computed stats with window bounds

Verifies E2E test #1 baseline values:
- eggs_total_pcs = 12
- feed_total_g = 6000, feed_layers_g = 4615
- cost_per_egg_all = 0.600, cost_per_egg_layers = 0.462
- layer_eligible_bird_days = 10

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 09:25:39 +00:00
d53decdb66 feat: add product collection event handling
Implements Step 4.3 from the plan:
- Add selection/resolver.py with basic resolve_selection for validating
  animal IDs exist and are alive
- Add ProductsProjection placeholder (stats tables added in Step 4.4)
- Add ProductService with collect_product() function
- Add PRODUCT_COLLECTED to EventAnimalsProjection for linking events
  to affected animals
- Full test coverage for all new components

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 09:08:13 +00:00
fa3c99b755 feat: add feed given event handling
- Add FEED_GIVEN to FeedInventoryProjection with apply/revert
- Add give_feed method to FeedService
- Block feed given if no purchase exists <= ts_utc
- Validate feed type and location existence
- 13 new tests for give_feed functionality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 08:11:36 +00:00
5c10a750ce feat: add feed inventory schema and purchase service
Implement FeedPurchased event handling:
- Add migration for feed_inventory table
- Create FeedInventoryProjection to track purchases
- Create FeedService with purchase_feed method
- Calculate price_per_kg_cents from bag details

Purchases accumulate in inventory with:
- purchased_kg, given_kg, balance_kg tracking
- Last purchase price stored in cents
- Timestamps for last purchase/given

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 08:02:24 +00:00
0511ed7bca feat: add animal tagging projection and service
Implement AnimalTagged and AnimalTagEnded event handling:
- Add migration for tag_suggestions table
- Create TagProjection for tag intervals and suggestions
- Update EventAnimalsProjection to handle tag events
- Add add_tag() and end_tag() to AnimalService

Key behaviors:
- No-op idempotence (adding active tag or ending inactive tag)
- Updates live_animals_by_location.tags JSON array
- Tracks tag usage statistics in tag_suggestions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 07:51:20 +00:00
dc7700da20 feat: add animal attributes update projection and service
Implement AnimalAttributesUpdated event handling:
- Update IntervalProjection to close old attr intervals and open new ones
- Update AnimalRegistryProjection to update registry tables
- Update EventAnimalsProjection to track event-animal links
- Add update_attributes() to AnimalService

Only attributes that actually change create new intervals.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 07:18:17 +00:00
b89ea41d63 feat: add animal movement projection and service
Implement AnimalMoved event handling:
- Update AnimalRegistryProjection for move events
- Update IntervalProjection to close/open location intervals
- Update EventAnimalsProjection to link move events to animals
- Add move_animals() to AnimalService with validations

Validations include:
- Destination location must exist and be active
- All animals must be from a single location
- Cannot move to the same location as current

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 07:02:19 +00:00
876e8174ee feat: add animal cohort creation projection and service
Implements Step 3.3: Animal Cohort Creation

- Add AnimalRegistryProjection for animal_registry and live_animals_by_location
- Add EventAnimalsProjection for event_animals link table
- Add IntervalProjection for location and attribute intervals
- Add AnimalService with create_cohort() for coordinating event + projections
- Add seeded_db fixture to conftest.py
- Update projections/__init__.py with new exports

All operations atomic within single transaction. Includes validation for
location (exists, active) and species (exists, active).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 06:52:23 +00:00
e3d65283da feat: add interval projection schema and models
Add time-series tracking tables for animal location, tag, and attribute
history. Each interval represents a period when an animal had a specific
state, with open intervals (end_utc=NULL) for current state.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 19:51:28 +00:00
739b7bfe32 feat: add animal registry schema and models
Add database tables for animal tracking:
- animal_registry: main snapshot table with all animal attributes
- live_animals_by_location: denormalized view for fast roster queries
- animal_aliases: merge tracking for when animals are discovered to be same

Includes Pydantic models and comprehensive tests for all constraints.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 18:59:24 +00:00
42cb1ed7cb feat: add projection infrastructure for event processing
Add base class, registry, and processor for the projection system:
- Projection ABC with apply/revert methods
- ProjectionRegistry for mapping event types to projections
- process_event/revert_event functions for dispatching

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 18:47:11 +00:00
80784ff636 feat: add event payload models with tag normalization
Implements Step 2.3 of the plan:
- 17 Pydantic payload models for all event types per spec §6
- 6 enums: Sex, ReproStatus, LifeStage, AnimalStatus, Origin, Outcome
- Tag normalization per spec §20 (lowercase, spaces→hyphens, max 32 chars)
- ULID validation utilities
- 38 tests covering payloads, enums, and tag normalization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 18:34:41 +00:00
29d5d3f8ff feat: add event store with nonce and clock skew validation
Implements Step 2.2 of the plan:
- EventStore class with append_event, get_event, list_events, is_tombstoned
- Event type constants for all 17 event types from spec
- ClockSkewError for rejecting timestamps >5 min in future
- DuplicateNonceError for idempotency nonce validation
- 25 tests covering all event store functionality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 07:35:05 +00:00
cc32370d49 perf: speed up test suite with parallel execution
- Enable pytest-xdist with -n auto for parallel test execution
- Consolidate migrated_db fixture in conftest.py (was duplicated in 4 files)
- Remove local fixture definitions and unused imports from test files

Test execution: ~24s -> ~5s (~5x speedup)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 07:25:18 +00:00
262739d8ec feat: add event tables schema and models
Create migration for events, event_revisions, event_tombstones,
idempotency_nonces, and event_animals tables with ULID checks
and JSON validation. Add Pydantic models with field validators.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 21:37:19 +00:00
4579229734 feat: add repositories and reference data seeder
Implements Step 1.5: Creates ULID generation utility, repositories for
all reference types (species, locations, products, feed_types, users),
and an idempotent seeder that populates initial data. Updates CLI seed
command to run migrations and seed data.

Seed data:
- 3 users (ppetru, ines as admin; guest as recorder)
- 8 locations (Strip 1-4, Nursery 1-4)
- 3 species (duck, goose active; sheep inactive)
- 7 products (egg.duck, meat, offal, fat, bones, feathers, down)
- 3 feed types (starter, grower, layer - 20kg bags)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 19:40:55 +00:00
2e28827683 feat: add reference tables schema and Pydantic models
Implements Step 1.4: Creates migration for species, locations, products,
feed_types, and users tables with full CHECK constraints. Adds Pydantic
models with validation for all reference types including enums for
ProductUnit and UserRole.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 19:18:08 +00:00
7d7cd2bb57 feat: add migration framework with FastMigrate integration
- Add migrations.py with create_migration, run_migrations, get_db_version
- Implement CLI migrate and create-migration commands
- Use FastMigrate's sequential 0001-*.sql naming convention
- Add comprehensive unit, integration, and E2E tests (35 tests)
- Add fresh_db_path and temp_migrations_dir test fixtures

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 18:25:28 +00:00
d8910d6571 feat: add database module with connection factory and transactions
Implements Step 1.2:
- constants.py: END_OF_TIME_UTC = 32503680000000 (year 3000 sentinel)
- db.py: get_db() with pragmas (WAL, synchronous=FULL, foreign_keys, busy_timeout)
- db.py: transaction() context manager with BEGIN IMMEDIATE

Includes 12 TDD tests for pragmas, commit/rollback, and concurrent writes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 17:58:29 +00:00
61f704c68d feat: add config module with environment variable handling
Implements Step 1.1 config.py with Pydantic Settings:
- PORT (default 3366), DB_PATH, BASE_PATH
- AUTH_HEADER_NAME, TRUSTED_PROXY_IPS (comma-separated)
- CSRF_SECRET (required), CSRF_COOKIE_NAME
- SEED_ON_START, LOG_LEVEL (validated), METRICS_ENABLED

Includes 28 TDD tests covering defaults, overrides, and validation.
Also fixes pytest pythonpath configuration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 17:54:21 +00:00
d213abf9d9 chore: add pre-commit hook with ruff and pytest
- Add git pre-commit hook running ruff check, ruff format, pytest
- Fix import ordering in conftest.py
- Add placeholder test for test infrastructure
- Generate flake.lock

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 17:41:32 +00:00
c0b939627b feat: initial project setup with implementation plan
- Add PLAN.md with 40-step checklist across 10 phases
- Add CLAUDE.md with project-specific instructions
- Set up nix flake with FastHTML/MonsterUI dependencies
- Create Python package skeleton (src/animaltrack)
- Vendor FastHTML and MonsterUI documentation
- Add Docker build configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 17:37:16 +00:00