# fpna_month_end SQL model generated by Power Migrate 0.1.0a1 from `fpna_month_end.xlsx` (SHA-256 `1ee4a1f3e378e3e9...`), duckdb dialect, in no-AI mode: every table, column and expression comes from deterministic rules. ## Layout | File | Purpose | | --- | --- | | `model.sql` | One `CREATE TABLE ... AS SELECT` step per logic block, in dependency order, over one table per worksheet keyed by `row_num`; final views named after the sheets | | `functions.sql` | Excel semantics as SQL macros (`xl_round`, `xl_pmt`, `xl_edate`, ...). Run it first | | `manifest.json` | Which table holds each sheet, which physical column holds each Excel column (`"D"` numbers, `"D_txt"` text, `"D_bool"` logicals), which step wrote each block | | `model.py` | A thin harness: loads a Book's inputs into DuckDB, runs the SQL, reads the results back. `compute(book)` and `load_inputs()` as in the Python target | | `inputs.json`, `expected.json`, `baseline.json`, `test_model.py` | The workbook's inputs, Excel's stored values, the cells that reconciled, and the regression test | ## Run it ```python from fpna_month_end import compute, load_inputs book = compute(load_inputs()) # needs the duckdb package print(book["Sheet1"]["B7"].v) ``` Or load `cells(sheet, row_num, col, num, txt, flag)` and `sheet_rows(sheet, row_num)` yourself and run `functions.sql` then `model.sql` on any DuckDB. ## Policies Excel has one dynamic cell type; SQL columns are typed. The generator infers one type per block and keeps a separate physical column per type where a sheet column mixes them. Excel errors and the empty string are `NULL`; a blank input counts as 0 in arithmetic, as in Excel; text compares case-insensitively. The reconciliation report counts every cell that matched only under these policies. Dates are Excel serial numbers (`xl_to_date` converts). 1 of 73 blocks were not converted (or depend on one that was not); each is marked `-- NOT CONVERTED` in `model.sql` with its reason and is listed in the reconciliation report. This package shows tested equivalence with the workbook's stored values for the cells in `baseline.json`; it is not a guarantee for other inputs.