# Bookkeeping Practices: Client Portal Using Laravel

## Summary
A client portal blueprint for bookkeeping practices built with Laravel on Ample. Domain schema:
- **client_entities** (legal_name, entity_type, accounting_software, period_cadence): clients and their bookkeeping cadence.
- **engagements** (client_entity_id, period_start, period_end, close_status): monthly or quarterly close engagements.
- **document_requests** (engagement_id, category, due_at, status, uploaded_object_key): receipts, statements and payroll summaries requested.
- **close_checklists** (engagement_id, item, done_at): close tasks per period.
- **document_access** (document_id, principal_reference, role, granted_at): who may read which document.

## Public Information
- Service packages and cadence
- Onboarding checklist
- Contact details

Kept out of scope until handling is reviewed:
- Bank statements and receipts
- Payroll data
- Login credentials for accounting software  
**Important:** Never store client accounting-software credentials in these flows; financial records are sensitive and no compliance is claimed.

## Workflow Steps
1. **Model the bookkeeping practices domain:** Create the tables `client_entities`, `engagements`, `document_requests`, `close_checklists`, `document_access`. Clients and their bookkeeping cadence lives in `client_entities`; keep the sensitive classes (bank statements and receipts, payroll data, login credentials for accounting software) out of this schema.
2. **Model client entities and engagement periods:** Every document belongs to one engagement.
3. **Authorize by client entity and role:** Before any storage access (401 without identity, 403 for the wrong client).
4. **Store documents:** In the private bucket and stream them through the app.
5. **Deploy and verify:** The negative authorization tests and an authorized download.
6. **Run the synchronous deploy once:** Read the result. Re-running with no change is a no-op.

## Tested Configuration
- **Template:** php-8.5
- **Runtime:** php
- **Size:** s-1vcpu-1gb
- **Install:** `composer install --no-dev --prefer-dist --no-interaction --no-progress --optimize-autoloader`
- **Start:** `frankenphp php-server --listen :$PORT --root public`

## Input Schema
```json
{
  "additionalProperties": false,
  "properties": {
    "env": {
      "description": "Encrypted environment variables",
      "items": {
        "pattern": "^[A-Z][A-Z0-9_]*=.*$",
        "type": "string"
      },
      "maxItems": 50,
      "type": "array"
    },
    "name": {
      "description": "App name",
      "maxLength": 63,
      "minLength": 1,
      "pattern": "^[a-z0-9-]+$",
      "type": "string"
    },
    "path": {
      "description": "Project directory or ample.toml service",
      "maxLength": 512,
      "minLength": 1,
      "type": "string"
    },
    "release_command": {
      "description": "Migration command run before activation",
      "maxLength": 512,
      "type": "string"
    }
  },
  "required": ["env", "name", "path"],
  "type": "object"
}
```

## Cost Estimate
- **Currency:** USD
- **Monthly Amount:** 10.0
- **Basis:** Size prices from `pricing.toml` at build revision `1ac5595375130d45290090e82ed0f554ccd45405-dirty`
  - **Components:**
    - App server (s-1vcpu-1gb): $5.00/month
    - Managed PostgreSQL database (s-1vcpu-1gb): $5.00/month  
**Note:** Always-on monthly price of the tested sizes; apps and databases auto-pause when idle.

## Limitations
- The technical basis (private document library on Laravel) was verified with the pattern fixture; the bookkeeping practices schema and workflow are original designs for this blueprint and were not executed as a separate application.
- No health, financial, privacy, or other compliance claim is made.
- **Important:** Public content and synthetic examples only until actual data-handling requirements have been reviewed.
