feat(account): CLI lifecycle conturi + accounts.active (PRD 3.1)

Inlocuieste crearea conturilor prin INSERT SQL manual cu un tool admin
dedicat, simetric cu tools/apikey.py. Fundatia Etapei 3 (3.2/3.3).

- app/accounts.py: create_account/set_active/list_accounts (helper pur,
  partajat CLI + viitor flux web 3.3). Normalizeaza CUI (trim+upper),
  prinde IntegrityError -> ValueError cu cauza+fix.
- accounts.active (lifecycle cont) + index unic partial ux_accounts_cui
  (unicitate la nivel de index, fara fereastra de coliziune). Migrare
  idempotenta in _migrate.
- tools/account.py: create (--name/--cui/--inactive/--with-key atomic),
  list [--pending], activate/deactivate --account N. Erori -> exit 2.
- 20 teste noi (12 helper + 8 CLI); suita 299 passed.

active e inert pana la gate-ul worker din 3.3 (documentat).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-17 12:38:13 +00:00
parent 6515de415b
commit 1c5b0cbc18
8 changed files with 475 additions and 5 deletions

View File

@@ -1,6 +1,6 @@
# PRD 3.1 — Creare cont nou
**Stare**: aprobat
**Stare**: verify-pass
> Proces complet: `docs/ROADMAP.md` §5. Contract RAR (sursa de adevar): `docs/api-rar-contract.md`.
> Starea trece: `draft → aprobat → in-executie → verify-pass → inchis` (actualizata de lead).
@@ -148,5 +148,30 @@ nu blocheaza livrabila.
## Raport VERIFY
> Completat de subagentul verificator (context curat) in faza VERIFY — vezi ROADMAP §5.6.
> PASS/FAIL per criteriu, cu dovezi. Lipseste pana la VERIFY.
> Executat 2026-06-17. Suita completa: **299 passed** (20 teste noi: 12 helper + 8 CLI).
**US-001 — PASS**
- [x] `accounts.active INTEGER NOT NULL DEFAULT 1` in `schema.sql` + migrat idempotent in `_migrate`
(conturi existente raman active; default id=1 activ). Dovada: `test_foundation` + migrare ALTER.
- [x] `create_account(conn, name, cui=None, active=True) -> int` insereaza + intoarce id.
`test_create_account_returneaza_id`.
- [x] `name` gol/whitespace → `ValueError`, nu insereaza. `test_create_account_name_gol_ridica_eroare`.
- [x] `cui` duplicat → `ValueError` (cauza+fix, numeste contul); `cui=None` multiplu OK.
`test_create_account_cui_duplicat_respins`, `test_create_cui_null_multiplu_permis`.
- [x] `set_active` comuta; inexistent → `ValueError`; idempotent. `test_set_active_*`.
- [x] `list_accounts``id,name,cui,active,created_at`, ordonat, FARA `rar_creds_enc`.
`test_list_accounts_ordonat_fara_creds`.
**US-002 — PASS** (E2E PRD reprodus: `create --inactive --with-key` → id=2 + cheie; `activate` → list `activ=da`)
- [x] `create --name [--cui] [--inactive]` creeaza (implicit activ), tipareste id. `test_create_afiseaza_id`.
- [x] `--with-key` emite cheie afisata o data, atomic (rollback pe esec). `test_create_with_key_emite_cheie`,
`test_with_key_atomic_pe_cui_duplicat`.
- [x] `activate`/`deactivate --account N` comuta. `test_activate_comuta_starea`.
- [x] erori → stderr + exit 2. `test_create_cui_duplicat_exit_2`, `test_activate_inexistent_exit_2`.
- [x] `list` tipareste tabelul; `list --pending` filtreaza. `test_list_afiseaza_activ`, `test_list_pending_filtreaza`.
- [x] `init_db()` la start.
**Addendum** — A1 (index unic partial `ux_accounts_cui` + normalizare trim/upper, `test_create_cui_normalizat`),
A3 (`--account` pe activate/deactivate), A4 (mesaj cauza+fix), A5 (`--with-key` atomic), A6 (`list --pending`;
`set-password` deferat la 3.3), A7 (teste RED suplimentare) — toate aplicate. A2 (`active` inert pana la 3.3)
documentat in `app/accounts.py` + `tools/account.py`.