diff --git a/core/migrations/0017_alter_payrolladjustment_type.py b/core/migrations/0017_alter_payrolladjustment_type.py new file mode 100644 index 0000000..c077efb --- /dev/null +++ b/core/migrations/0017_alter_payrolladjustment_type.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2026-05-15 17:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0016_worker_pay_type'), + ] + + operations = [ + migrations.AlterField( + model_name='payrolladjustment', + name='type', + field=models.CharField(choices=[('Bonus', 'Bonus'), ('Overtime', 'Overtime'), ('Deduction', 'Deduction'), ('Loan Repayment', 'Loan Repayment'), ('New Loan', 'Loan'), ('Advance Payment', 'Advance'), ('Advance Repayment', 'Advance Repaid'), ('Salary', 'Salary')], max_length=50), + ), + ] diff --git a/docs/plans/2026-05-15-manager-salaried-pay-plan.md b/docs/plans/2026-05-15-manager-salaried-pay-plan.md index 775ff29..8f554d2 100644 --- a/docs/plans/2026-05-15-manager-salaried-pay-plan.md +++ b/docs/plans/2026-05-15-manager-salaried-pay-plan.md @@ -186,6 +186,14 @@ git commit -m "feat: add Worker.pay_type discriminator + is_salaried property" - Modify: `core/models.py:289` (`PayrollAdjustment.TYPE_CHOICES`) - Modify: `core/views.py` (`ADDITIVE_TYPES` — find with `grep -n "^ADDITIVE_TYPES" core/views.py`) +- Create: `core/migrations/0017_alter_payrolladjustment_type.py` (auto-generated; + depends on `0016_worker_pay_type`). **Adding a value to + `PayrollAdjustment.TYPE_CHOICES` DOES require a migration in this codebase** — + Django's migration autodetector tracks `choices` in field state, so it emits + a no-op `AlterField` (choices metadata only; no data or schema change). + Precedent: `0012_alter_payrolladjustment_type_display_labels.py` was generated + for the exact same kind of `TYPE_CHOICES` edit. Skipping it leaves + `makemigrations --check` non-clean — a deploy-hygiene defect. - Test: `core/tests.py` (`ManagerSalariedPayTypeRegistrationTests`) **Step 1: Write the failing tests** @@ -207,7 +215,9 @@ class ManagerSalariedPayTypeRegistrationTests(TestCase): **Step 3: Implement** `core/models.py` — append to `PayrollAdjustment.TYPE_CHOICES` (DB value == -label, so NO UI-vs-DB drift — see CLAUDE.md): +label, so NO UI-vs-DB drift — see CLAUDE.md). Note: "DB value == label" only +means the displayed text equals the stored string; it does **not** mean the +change is migration-free — see the migration bullet above. ```python ('Salary', 'Salary'), @@ -217,15 +227,25 @@ label, so NO UI-vs-DB drift — see CLAUDE.md): net pay). Leave `DEDUCTIVE_TYPES` untouched. Add a short inline comment: `# 'Salary' = manager / fixed-salary monthly pay (additive).` +Then generate the required choices migration: +`USE_SQLITE=true DJANGO_DEBUG=true python manage.py makemigrations core` +Expected: creates `core/migrations/0017_alter_payrolladjustment_type.py` — a +single `AlterField` on `payrolladjustment.type` that changes only `choices` +(depends on `0016_worker_pay_type`; no data migration, no other model touched). + **Step 4: Run — Expected:** PASS (2 tests). Then run the FULL suite to confirm no existing test hard-codes the choices length: `USE_SQLITE=true DJANGO_DEBUG=true python manage.py test core.tests -v 2` -Expected: still green (175 now). +Expected: still green (175 now; the migration is a no-op for behavior). Finally +confirm a clean tree: +`USE_SQLITE=true DJANGO_DEBUG=true python manage.py makemigrations --check --dry-run core` +must report "No changes detected" (exit 0). **Step 5: Commit** ```bash -git add core/models.py core/views.py core/tests.py +git add core/models.py core/views.py core/tests.py \ + core/migrations/0017_alter_payrolladjustment_type.py git commit -m "feat: register 'Salary' PayrollAdjustment type as additive" ```