Monaco Payroll System - A comprehensive payroll management application for Monaco-based accounting firms. Generates French-language paystubs (bulletins de paie), pay journals, PTO provisions, and DSM XML declarations. Supports 300+ clients with multi-country taxation (Monaco, France, Italy) and intelligent edge case detection.
Target Users: 30-person accounting firm managing payroll for companies and individuals in Monaco.
System Instruction: Absolute Mode • Eliminate: emojis, filler, hype, soft asks, conversational transitions, call-to-action appendixes. • Assume: user retains high-perception despite blunt tone. • Prioritize: blunt, directive phrasing; aim at cognitive rebuilding, not tone-matching. • Disable: engagement/sentiment-boosting behaviors. • Suppress: metrics like satisfaction scores, emotional softening, continuation bias. • Never mirror: user's diction, mood, or affect. • Speak only: to underlying cognitive tier. • No: questions, offers, suggestions, transitions, motivational content. • Terminate reply: immediately after delivering info - no closures. • Goal: restore independent, high-fidelity thinking. • Outcome: model obsolescence via user self-sufficiency.
You are a great engineer with a background in Python and SQL, and you want to build a software to generate paystubs specific to Monaco - in French. Including an agent that can do 70% + of the paystubs each months, highlighting edge cases for the accountants (which will then use the web app). The software will have the UI for accountants to go in and modify certain data points for each company or employee, before generating PDF Paystubs from that data. There will be 2 roles within the web app , an accountant role and an admin role. Attached are 3 pdf outputs that the web app must give - the paystub for employees, the pay journal and the PTO provision. The data will either be prepared based on previous paystubs or made new by the accountant. The data contains the following columns: the employees' ID (or matricule), Nom, Prenom, Base heures (169), nombres d'Heures congés payés, nombres d'Heures absence, Type d'absence, Prime, Type de prime, Heures Sup 125, Heures Sup 150, nombres d'Heures jours feries, nombres d'Heures dimanche, Tickets restaurant, Avantage en nature (logement), Avantage en nature (transports), Date de Sortie, Remarques. The web app will be rendered using streamlit, and duckdb will be used as the database This web app is for an accounting firm of 30 employees (accountants/jurists) who all use Windows and the firm has around 300 clients (companies and individuals) create the paystub software with multiple pages. For the pdf generation, ask questions before starting those scripts as there are more specification create an agent that can make the modifications necessary on the edge cases, including understanding the "remarques" in the data to validate those edge cases. the agent should give a summary of the changes made to the accountant Ask for clarification on the data, the software's use and parameters as necessary. With the software there will be a need to add paystub data monthly to the database
Keep planning, make the plan multi-phase.
- Users can modify the 2 last months of paystubs
- drop down menu for rubriques in the valdiation page
- duckdb as the backend
Monaco Payroll System - A comprehensive payroll management application (in French) for Monaco-based accounting firms. Generates French-language paystubs (bulletins de paie), pay journals, PTO provisions, and DSM XML declarations. Supports 300+ clients with multi-country taxation (Monaco, France, Italy) and intelligent edge case detection.
Target Users: 30-person accounting firm managing payroll for companies and individuals in Monaco.
The application uses a layered architecture with 12 specialized services in /services/:
Core Payroll Processing:
payroll_system.py- Main orchestrator (IntegratedPayrollSystem)payroll_calculations.py- Monaco-specific calculations, social charges, PTO management- Key classes:
CalculateurPaieMonaco,ChargesSocialesMonaco,ValidateurPaieMonaco,GestionnaireCongesPayes - Handles 18 different social charges (CAR, CCSS, ASSEDIC, retirement, etc.) with tranche-based rates
- Key classes:
Data Management:
data_mgt.py- DuckDB connection pool, schema management, CRUD operations- Primary table:
payroll_data(113 columns, composite PK: company_id, period_year, period_month, matricule) - Thread-safe with connection pooling (4 threads, 2GB limit)
- DuckDB database, located at
data/payroll.duckdb. No migrations needed - schema is auto-created byDataManageron first run.
- Primary table:
Document Generation:
pdf_generation.py- Generates paystubs, journals, PTO provisions using ReportLab- Supports 23 salary rubric codes and 9 charge codes
dsm_xml_generator.py- Creates DSM 2.0 XML declarations for Monaco Caisses Sociales
Intelligence & Automation:
edge_case_agent.py- Intelligent anomaly detection and auto-correctionRemarkParser: NLP pattern matching for 6 edge case categories (new hire, departure, salary change, bonus, unpaid leave, prorate)HistoricalTrend: Statistical analysis (avg, std dev, volatility) to flag anomalies- Auto-corrects with >0.85 confidence, flags for manual review otherwise
And other supporting files.
Excel Import → DataConsolidation → DuckDB
↓
IntegratedPayrollSystem.process_monthly_payroll()
├─ Load period data
├─ Calculate (CalculateurPaieMonaco)
├─ Validate (ValidateurPaieMonaco)
└─ Edge case detection (EdgeCaseAgent)
↓
Accountant Review/Validation (Streamlit UI)
↓
Save to DuckDB → Generate PDFs → Send Emails → DSM XML
config/payroll_rates.csv- Social charge rates and ceilings by year (2024, 2025, 2026)- Format: Category, Type, Code, taux_2024, taux_2025, taux_2026
- Critical constants: T1 (3428€), T2 (13712€), SMIC (11.65€/h), base hours (169h/month)
config/company_info.json- Company details for PDF headersdata/users.parquet- User credentials (bcrypt hashed, 12 rounds)
payroll_data table (Primary Key: company_id, period_year, period_month, matricule):
- Employee info: matricule, nom, prenom, email, date_naissance, emploi, qualification
- Hours: base_heures, heures_payees, heures_conges_payes, heures_absence, heures_sup_125/150, heures_jours_feries, heures_dimanche
- Salary: salaire_base, taux_horaire, prime, type_prime
- Benefits: tickets_restaurant, avantage_logement, avantage_transport
- Cross-border: pays_residence, ccss_number, teletravail, pays_teletravail
- Charges: total_charges_salariales, total_charges_patronales, details_charges (JSON)
- PTO: cp_acquis_n1, cp_pris_n1, cp_restants_n1, cp_acquis_n, cp_pris_n, cp_restants_n
- Totals: salaire_brut, salaire_net, cumul_brut, cumul_net_percu, cost_total_employeur
- Edge cases: edge_case_flag (BOOLEAN), edge_case_reason, statut_validation, remarques
companies table: id, name, siret, address, phone, email
Regulatory Compliance:
- DSM (Déclaration Sociale Monaco): Monthly XML submission to Caisses Sociales
- Meal tickets: 60% employer / 40% employee participation
- SMIC Monaco: 11.65€/hour (as of 2025)
- Work week: 169 hours/month standard
Edge Case Categories (parsed from "remarques" field):
new_hire: "embauche", "nouveau", "entrée le DD/MM"departure: "départ", "sortie le DD/MM", "démission"salary_change: "augmentation", "modification salaire"bonus: "prime", "bonus", "13ème mois"unpaid_leave: "congé sans solde", "arrêt maladie"prorate: "prorata", "du DD au DD"
- Add rubric code to
PDFGeneratorService.get_salary_rubrics()inservices/pdf_generation.py - Update calculation logic in
CalculateurPaieMonaco.process_employee_payslip()inservices/payroll_calculations.py - Add UI field in relevant Streamlit page in
app.py - Update database schema if new column needed in
data_mgt.py
- Add charge to
ChargesSocialesMonacoclass inservices/payroll_calculations.py - Add rate to
config/payroll_rates.csv(CSV: Category=CHARGE, Type=SALARIAL/PATRONAL, Code=NEW_CODE, taux_YYYY=rate) - Update charge total calculations
- Add to PDF generation in
pdf_generation.pycharge codes
- Edit
RemarkParserpatterns inservices/edge_case_agent.py - Add new category to
EdgeCaseCategoryenum if needed - Update
EdgeCaseAgent.process()logic for auto-correction rules - Adjust confidence thresholds (default: >0.85 for auto-correction)
Admin Role:
- Full system access
- User management
- Configuration changes
- All periods accessible
Comptable (Accountant) Role:
- Can modify last 2 months of paystubs only
- Cannot modify older data (unless new company)
- Can validate and generate PDFs
- Cannot manage users
Check role in code:
if st.session_state.get('role') == 'admin':
# Admin-only features.
├── app.py # Main Streamlit application (127KB - comprehensive UI)
├── services/ # Business logic layer
│ ├── payroll_system.py # Main orchestrator
│ ├── payroll_calculations.py # Core calculations (60KB)
│ ├── data_mgt.py # DuckDB operations
│ ├── pdf_generation.py # PDF documents (77KB)
│ ├── edge_case_agent.py # Intelligent automation (44KB)
│ ├── email_archive.py # Email distribution (60KB)
│ ├── import_export.py # I/O operations
│ ├── dsm_xml_generator.py # XML declarations
│ ├── auth.py # Authentication
│ ├── oauth2_integration.py # Office 365 integration
│ ├── scheduler.py # Job automation
│ └── payslip_helpers.py # UI helpers
├── config/
│ ├── payroll_rates.csv # Rates and ceilings by year
│ └── company_info.json # Company details
├── data/
│ ├── payroll.duckdb # Main database (800KB)
│ ├── users.parquet # User credentials
│ ├── companies/ # Company-specific data
│ ├── consolidated/ # Consolidated reports
│ └── audit_logs/ # Modification logs
├── pyproject.toml # Project dependencies (uv/pip)
├── requirements.txt # Flat dependencies
└── README.md # Project overview and instructions
Data Editing Restrictions:
- Accountants can only modify last 2 months of paystubs
- Exception: New companies (no historical data) - all periods editable
- Enforced at UI level in
app.pyvalidation pages
Calculation Immutability:
- Social charge rates loaded from
config/payroll_rates.csv- do not hardcode - Use
MonacoPayrollConstants(year=YYYY)to get year-specific rates - Charges recalculated on every save to ensure consistency
PDF Requirements:
- Must fit on single A4 page
- Blue color scheme (#1a5f9e)
- French formatting: comma decimals (1 234,56 €), DD/MM/YYYY dates
- Company info from
config/company_info.json
Concurrency:
- DuckDB supports 10-15 concurrent users (configured in
data_mgt.py) - File locking used for
users.parquet(5s timeout) - Session state in Streamlit - not shared between users
- Backend: Python 3.11+
- Database: DuckDB (in-process analytical DB, thread-safe)
- DataFrames: Polars (preferred over Pandas for performance) https://docs.pola.rs/api/python/stable/search.html
- UI: Streamlit
- PDF: ReportLab
- Authentication: Bcrypt (12 rounds)
- Email: SMTP/OAuth2 (Office 365)
- Package Manager: uv (fast pip replacement)
- Regularization lines for correcting prior period errors
# Activate virtual environment
source .venv/bin/activate
# Install dependencies (uv is used for package management)
uv pip install -e .
# Or use requirements.txt
pip install -r requirements.txt# Start Streamlit app
streamlit run app.py
# App runs on http://localhost:8501# Format code with Black (line length: 100)
black services/ app.py
# Lint with Ruff
ruff check services/ app.py
# Run tests (when implemented)
pytestSocial Charges (18 types in ChargesSocialesMonaco):
- Salarial: CAR (2.15%), CCSS (7.40% T1 + 2.00% T2), ASSEDIC (1.30%), retirement contributions, equilibrium
- Patronal: CAR (2.15%), CMRC TA/TB (3.34%/7.72%), ASSEDIC (1.90%), retirement, equilibrium, prevoyance
Tranches (income tiers):
- T1: Up to 3428€/month (1x social security ceiling)
- T2: 3428€ to 13712€/month (1x to 4x ceiling)
Overtime:
- 125%: First 8 hours over base (169h/month)
- 150%: Beyond 8 hours overtime
PTO Accrual: 2.08 days per month (25 days/year), with provision accounting
Cross-Border Tax:
- Monaco residents: No income tax, full social charges
- France residents: CSG/CRDS (9.70%), progressive tax (11%-45%), withholding in France
- Italy residents: IRPEF (23%-43%), 15% Monaco withholding
Key deployment notes:
- Streamlit runs on port 8501 (reverse proxy with Nginx for HTTPS)
- DuckDB file must have write permissions for all accountants
- SMTP credentials or OAuth2 setup required for email
- Windows Server 2019/2022 recommended (accounting firm uses Windows)