38156-vm/CLAUDE.md
Konrad du Plessis c2c83a58ff Update CLAUDE.md with design conventions and fix mutable default arg in utils.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 01:33:48 +02:00

7.9 KiB

Fox Fitt LabourPay

Coding Style

  • Always add clear section header comments using the format: # === SECTION NAME ===
  • Add plain English comments explaining what complex logic does
  • The project owner is not a programmer — comments should be understandable by a non-technical person
  • When creating or editing code, maintain the existing comment structure

Project Overview

Django payroll management system for Fox Fitt Construction, a civil works contractor specializing in solar farm foundation installations. Manages field worker attendance, payroll processing, employee loans, and business expenses for solar farm projects.

Tech Stack

  • Django 5.x, Python 3.11, MariaDB
  • Bootstrap 5 with Material Design-inspired styling, vanilla JavaScript
  • PDF generation for payslips and receipts
  • SMTP email integration for automated document delivery
  • Apache reverse proxy with systemd service management

Project Structure

  • config/ — Django project settings, URLs, WSGI/ASGI entrypoints
  • core/ — Single main app containing ALL business logic, models, views, forms, templates, and migrations
  • ai/ — Local AI API integration module
  • media/workers/ids/ — Worker ID photo uploads
  • static/ — Source static files (custom CSS)
  • staticfiles/ — Collected static assets (Bootstrap, Popper.js, admin)

Key Business Rules

  • All business logic lives in the core/ app — do not create additional apps
  • Workers have a day_rate calculated automatically from monthly salary / 20 working days
  • PIN authentication (4-digit) exists alongside password auth for quick field access
  • Supervisors can only see their assigned projects and teams
  • Admins have full access to payroll, adjustments, and resource management
  • WorkLog is the central attendance record — links workers to projects on specific dates
  • Attendance logging includes conflict detection to prevent double-logging
  • Loans have automated repayment deductions during payroll processing
  • Cascading deletes use SET_NULL for supervisors to preserve historical data

Key Models

  • UserProfile — extends User with PIN and is_admin flag
  • Project — work sites/contracts with supervisor assignments
  • Worker — profiles with salary, day_rate, employment details
  • Team — groups of workers under a supervisor
  • WorkLog — daily attendance records (worker + project + date)
  • PayrollRecord — completed payments linked to WorkLog entries
  • PayrollAdjustment — bonuses, deductions, overtime, loan repayments
  • Loan — worker advances with balance tracking
  • ExpenseReceipt / ExpenseLineItem — business expense records

Commands

  • python manage.py runserver 0.0.0.0:8000 — run dev server
  • python manage.py migrate — apply database migrations
  • python manage.py collectstatic — collect static files for production
  • python manage.py setup_groups — configure permission groups
  • python manage.py update_permission_names — update permission display names
  • python manage.py check — system check (ignore staticfiles warnings about missing assets/ and node_modules/ dirs — pre-existing, harmless)

Development Workflow

  • Active development branch: ai-dev (PR target: master)
  • Admin check in views: is_admin(request.user) helper (imported at top of views.py)
  • "Unpaid" adjustment = payroll_record__isnull=True (no linked PayrollRecord)
  • POST-only mutation views pattern: check request.method != 'POST' → redirect, then process
  • Template UI pattern: Bootstrap 5 modals with dynamic JS wiring, data-* attributes on clickable elements

PayrollAdjustment Type Handling

  • BONUS / DEDUCTION — standalone, no linked objects
  • LOAN — links to Loan model via adj.loan FK; editing syncs loan amount/balance/reason; deleting cascades to Loan + unpaid repayments (blocked if paid repayments exist)
  • OVERTIME — links to WorkLog via adj.work_log FK; deleting removes worker from work_log.overtime_paid_to M2M (un-prices the OT)
  • LOAN_REPAYMENT — links to Loan via adj.loan FK; loan balance only changes during payment processing

Frontend Design Conventions

  • CSS variables defined in static/css/custom.css :root — always use var(--name) instead of hardcoding hex values
    • --primary-dark: #0f172a (navbar), --primary-color: #1e293b (headers), --accent-color: #10b981 (CTAs, brand green), --text-main: #334155, --bg-color: #f1f5f9
  • Icon library: Font Awesome 6 only (fas fa-*). Do NOT use Bootstrap Icons (bi bi-*)
  • CTA buttons: btn-accent (green) for all primary page-level actions. btn-primary (Bootstrap blue) for modal Save/Submit buttons only
  • Page titles: {% block title %}Page Name | Fox Fitt{% endblock %} — always use | separator, always "Fox Fitt" (never "LabourFlow")
  • Fonts: Inter (body) + Poppins (headings) loaded once in base.html. Do not add @import in custom.css
  • Cards: shadow-sm everywhere, never shadow-lg. Table headers use table-light class, never bg-light on <thead>
  • Email/PDF payslips: Worker name must be the dominant element — do NOT add prominent Fox Fitt branding (Spark reads the vendor name from the document)

Recent Work (Feb 2026)

Completed This Session

  1. Mobile responsiveness review & fixes — 17 issues found and fixed across all templates (card hover on touch, calendar compact view, form columns, chart heights, button stacking, heading sizes)
  2. Design consistency review — 25 issues identified across branding, colours, fonts, icons, buttons, cards, spacing, and tables
  3. Branding fixes — Replaced all "LabourFlow" → "Fox Fitt", standardized title separators to |
  4. Font cleanup — Removed duplicate Inter import from custom.css, removed duplicate inline body font rule from base.html, consolidated Google Fonts loading into single base.html link
  5. Icon standardization — Replaced all 13 Bootstrap Icon usages with Font Awesome equivalents, removed Bootstrap Icons CDN
  6. Colour variable standardization — Added --primary-dark CSS variable, replaced all inline hex colours with CSS variables
  7. Shadow & table standardization — All cards use shadow-sm, all theads use table-light, payslip tables changed from table-bordered to table-hover
  8. Button consistency — All page-level CTA buttons use btn-accent, login button inline override removed

Completed in Prior Sessions

  • Edit & Delete unpaid payroll adjustments feature
  • Advance Payment feature (plan written, not yet implemented)
  • Section header comments added to all core/ files
  • Bug/security fixes (mutable default args, queryset evaluation, timezone-aware dates, XSS protection, etc.)
  • Performance optimizations (database indexes, select_related/prefetch_related, aggregate queries)

Remaining from Design Review (Not Yet Fixed)

  • #10: Unify stat card styles between index.html (glassmorphism .stat-card) and payroll_dashboard (tinted bg-X bg-opacity-10)
  • #16: Inconsistent card header patterns across pages
  • #18: Create_receipt has dark primary-color card header while others don't
  • #19: Inconsistent page top spacing (some use dashboard-header + negative margin, some use py-5, some use mt-5)
  • #22: Footer is very basic — could use brand accent
  • #23: No loading/spinner states on form submissions
  • #25: Plain text empty states — could use icons

Pending Feature Work

  • Advance Payment feature — Full plan exists at .claude/plans/cozy-twirling-rainbow.md. Allows partial advance payments against earned wages with standalone payslip generation. Ready for implementation.

Important Context

  • Read APP_DOCUMENTATION.md for detailed workflows (attendance, payroll, expenses)
  • Environment variables loaded from ../.env
  • The owner (Konrad) is not a developer — explain changes clearly and avoid unnecessary complexity
  • This system handles real payroll for 14 field workers — accuracy is critical