# Phase 2: Data Model + REST API

**Status:** ⬜ Not Started
**Parent plan:** [PLAN.md](./PLAN.md)
**Domain:** backend

## Objective
Design and implement the complete data model (Prisma schema) and REST API endpoints for apartments, rooms, and all element types. Define shared types in `packages/shared`.

## Tasks

- [ ] Task 1: Design Prisma schema with models: Apartment, Room, Wall, WallOpening (doors/windows), ElectricalItem, FurnitureItem
- [ ] Task 2: Define shared TypeScript types in `packages/shared` matching Prisma models + API request/response DTOs
- [ ] Task 3: Implement Zod validation schemas in `packages/shared` for all create/update operations
- [ ] Task 4: Set up Prisma client generation and migration workflow in `apps/server`
- [ ] Task 5: Implement Apartment CRUD endpoints: `GET/POST /api/apartments`, `GET/PUT/DELETE /api/apartments/:id`
- [ ] Task 6: Implement Room CRUD endpoints: `GET/POST /api/apartments/:id/rooms`, `GET/PUT/DELETE /api/rooms/:id`
- [ ] Task 7: Implement Element endpoints for walls: `PUT /api/rooms/:id/walls` (bulk update room walls)
- [ ] Task 8: Implement Element endpoints for wall openings: `POST/PUT/DELETE /api/rooms/:id/openings`
- [ ] Task 9: Implement Electrical item CRUD: `GET/POST /api/rooms/:id/electrical`, `PUT/DELETE /api/electrical/:id`
- [ ] Task 10: Implement Furniture item CRUD: `GET/POST /api/rooms/:id/furniture`, `PUT/DELETE /api/furniture/:id`
- [ ] Task 11: Implement `GET /api/rooms/:id/full` — returns room with ALL elements (walls, openings, electrical, furniture) in a single response
- [ ] Task 12: Add Fastify error handling plugin — consistent error response format `{ error: string, statusCode: number }`
- [ ] Task 13: Register all routes using Fastify route plugin pattern (separate route files per resource)

## Data Model Design

```
Apartment
  - id: string (cuid)
  - name: string
  - address: string?
  - totalArea: float?
  - createdAt: DateTime
  - updatedAt: DateTime
  - rooms: Room[]

Room
  - id: string (cuid)
  - apartmentId: string (FK)
  - name: string
  - shape: JSON (array of {x, y} points defining the polygon)
  - width: float? (convenience for rectangular rooms)
  - height: float? (convenience for rectangular rooms)
  - wallHeight: float (default 2.7m)
  - order: int (display order)
  - createdAt: DateTime
  - updatedAt: DateTime
  - walls: Wall[]
  - openings: WallOpening[]
  - electricalItems: ElectricalItem[]
  - furnitureItems: FurnitureItem[]

Wall
  - id: string (cuid)
  - roomId: string (FK)
  - startX: float
  - startY: float
  - endX: float
  - endY: float
  - thickness: float (default 0.1m)
  - direction: enum (NORTH, SOUTH, EAST, WEST, OTHER)

WallOpening
  - id: string (cuid)
  - roomId: string (FK)
  - wallId: string (FK)
  - type: enum (DOOR, WINDOW)
  - positionAlongWall: float (0-1 normalized position)
  - width: float
  - height: float
  - elevationFromFloor: float (for windows)

ElectricalItem
  - id: string (cuid)
  - roomId: string (FK)
  - type: enum (OUTLET, SWITCH, JUNCTION_BOX, LIGHT_CEILING, LIGHT_WALL, CABLE_ROUTE)
  - x: float
  - y: float
  - wallId: string? (FK, for wall-mounted items)
  - elevationFromFloor: float?
  - rotation: float (degrees)
  - metadata: JSON? (extra properties per type)

FurnitureItem
  - id: string (cuid)
  - roomId: string (FK)
  - type: enum (BED, DESK, WARDROBE, SOFA, TABLE, CHAIR, SHELF, NIGHTSTAND, DRESSER, BOOKCASE, OTHER)
  - x: float
  - y: float
  - width: float
  - depth: float
  - height: float
  - rotation: float (degrees)
  - label: string?
```

## Files to Modify/Create
- `apps/server/prisma/schema.prisma` — complete data model
- `packages/shared/src/types/apartment.ts` — Apartment types
- `packages/shared/src/types/room.ts` — Room types
- `packages/shared/src/types/elements.ts` — Wall, WallOpening, ElectricalItem, FurnitureItem types
- `packages/shared/src/types/api.ts` — API request/response wrapper types
- `packages/shared/src/schemas/apartment.schema.ts` — Zod schemas for Apartment
- `packages/shared/src/schemas/room.schema.ts` — Zod schemas for Room
- `packages/shared/src/schemas/elements.schema.ts` — Zod schemas for elements
- `packages/shared/src/index.ts` — barrel exports (update)
- `apps/server/src/plugins/prisma.ts` — Prisma client Fastify plugin
- `apps/server/src/plugins/error-handler.ts` — error handling plugin
- `apps/server/src/routes/apartments.ts` — apartment route handlers
- `apps/server/src/routes/rooms.ts` — room route handlers
- `apps/server/src/routes/elements.ts` — wall, opening, electrical, furniture route handlers
- `apps/server/src/index.ts` — register route plugins (update)

## Acceptance Criteria
- Prisma schema validates and migrations generate successfully
- All CRUD endpoints return correct responses for happy paths
- Validation rejects malformed requests with clear error messages
- `GET /api/rooms/:id/full` returns nested room with all elements
- Shared types are importable from `@house-plan-maker/shared`
- Zod schemas match Prisma model constraints

## Notes
- Room shape stored as JSON array of polygon points — flexible for both rectangular and arbitrary shapes
- Wall direction enum helps with projection view mapping (Phase 6)
- ElectricalItem.wallId is nullable — ceiling-mounted items have no wall
- Use Prisma's cascade delete: deleting an apartment deletes its rooms, elements, etc.
- FurnitureItem dimensions are in meters

## Review Checklist
- [ ] All tasks completed
- [ ] Code follows project conventions
- [ ] No unintended side effects
- [ ] Build passes
- [ ] Tests pass (new + existing)

## Handoff to Next Phase
<!-- Filled in by the implementation agent after completing this phase -->
