half-orm-dev 0.17.4a2__tar.gz → 0.17.5a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. {half_orm_dev-0.17.4a2/half_orm_dev.egg-info → half_orm_dev-0.17.5a1}/PKG-INFO +77 -78
  2. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/README.md +76 -77
  3. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/hgit.py +1 -1
  4. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/migration_manager.py +46 -0
  5. half_orm_dev-0.17.5a1/half_orm_dev/migrations/0/17/5/01_update_pyproject_dependency.py +113 -0
  6. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/patch_manager.py +5 -1
  7. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/repo.py +2 -9
  8. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/pyproject.toml +1 -1
  9. half_orm_dev-0.17.5a1/half_orm_dev/version.txt +1 -0
  10. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1/half_orm_dev.egg-info}/PKG-INFO +77 -78
  11. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev.egg-info/SOURCES.txt +1 -1
  12. half_orm_dev-0.17.4a2/half_orm_dev/templates/Pipfile +0 -13
  13. half_orm_dev-0.17.4a2/half_orm_dev/version.txt +0 -1
  14. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/AUTHORS +0 -0
  15. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/LICENSE +0 -0
  16. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/__init__.py +0 -0
  17. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/bootstrap_manager.py +0 -0
  18. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/__init__.py +0 -0
  19. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/__init__.py +0 -0
  20. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/apply.py +0 -0
  21. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/bootstrap.py +0 -0
  22. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/check.py +0 -0
  23. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/clone.py +0 -0
  24. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/init.py +0 -0
  25. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/migrate.py +0 -0
  26. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/patch.py +0 -0
  27. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/release.py +0 -0
  28. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/restore.py +0 -0
  29. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/sync.py +0 -0
  30. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/todo.py +0 -0
  31. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/undo.py +0 -0
  32. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/update.py +0 -0
  33. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/commands/upgrade.py +0 -0
  34. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli/main.py +0 -0
  35. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/cli_extension.py +0 -0
  36. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/database.py +0 -0
  37. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/decorators.py +0 -0
  38. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/file_executor.py +0 -0
  39. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/migrations/0/17/1/00_move_to_hop.py +0 -0
  40. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/migrations/0/17/1/01_txt_to_toml.py +0 -0
  41. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/migrations/0/17/4/00_toml_dict_format.py +0 -0
  42. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/migrations/0/17/4/01_add_bootstrap_table.py +0 -0
  43. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/migrations/0/17/4/02_move_patches_to_subdirs.py +0 -0
  44. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/modules.py +0 -0
  45. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/patch_validator.py +0 -0
  46. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/patches/0/1/0/00_half_orm_meta.database.sql +0 -0
  47. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/patches/0/1/0/01_alter_half_orm_meta.hop_release.sql +0 -0
  48. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/patches/0/1/0/02_half_orm_meta.view.hop_penultimate_release.sql +0 -0
  49. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/patches/log +0 -0
  50. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/patches/sql/half_orm_meta.sql +0 -0
  51. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/release_file.py +0 -0
  52. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/release_manager.py +0 -0
  53. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/scripts/repair-metadata.py +0 -0
  54. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/.gitignore +0 -0
  55. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/MANIFEST.in +0 -0
  56. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/README +0 -0
  57. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/conftest_template +0 -0
  58. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/git-hooks/pre-commit +0 -0
  59. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/git-hooks/prepare-commit-msg +0 -0
  60. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/init_module_template +0 -0
  61. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/module_template_1 +0 -0
  62. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/module_template_2 +0 -0
  63. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/module_template_3 +0 -0
  64. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/relation_test +0 -0
  65. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/sql_adapter +0 -0
  66. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/templates/warning +0 -0
  67. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev/utils.py +0 -0
  68. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev.egg-info/dependency_links.txt +0 -0
  69. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev.egg-info/requires.txt +0 -0
  70. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/half_orm_dev.egg-info/top_level.txt +0 -0
  71. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/pyproject.toml +0 -0
  72. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/setup.cfg +0 -0
  73. {half_orm_dev-0.17.4a2 → half_orm_dev-0.17.5a1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: half_orm_dev
3
- Version: 0.17.4a2
3
+ Version: 0.17.5a1
4
4
  Summary: half_orm development Framework.
5
5
  Author-email: Joël Maïzi <joel.maizi@collorg.org>
6
6
  License-Expression: GPL-3.0-or-later
@@ -35,7 +35,7 @@ Dynamic: requires-dist
35
35
 
36
36
  > **Please report any issues at [GitHub Issues](https://github.com/half-orm/half-orm-dev/issues)**
37
37
 
38
- **Git-centric patch management and database versioning for half-orm projects**
38
+ **Git-centric patch management and PostgreSQL database versioning for half-orm projects**
39
39
 
40
40
  [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
41
41
  [![License: GPLv3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
@@ -53,6 +53,7 @@ Modern development workflow for PostgreSQL databases with automatic code generat
53
53
  - **Git-centric workflow**: Patches stored in Git branches with semantic versioning
54
54
  - **Test-Driven Development**: **Automatic validation** - tests run before integration, patches blocked if tests fail
55
55
  - **Code generation**: Python classes auto-generated from schema changes
56
+ - **Data bootstrapping**: Initialize reference data and configurations with tracked scripts
56
57
  - **Safe deployments**: Sequential releases with automatic backups and validation
57
58
  - **Team collaboration**: Distributed locks, branch management, conflict prevention
58
59
  - **Cloud-friendly**: No superuser privileges required (works on AWS RDS, Azure, GCP)
@@ -74,10 +75,11 @@ half_orm dev patch merge
74
75
 
75
76
  # Behind the scenes:
76
77
  # 1. Creates temporary validation branch
77
- # 2. Merges ALL patches in release context
78
- # 3. Runs pytest automatically
79
- # 4. If PASS → merges into release, status → "staged"
80
- # 5. If FAILnothing committed, temp branch deleted
78
+ # 2. Restores database from production schema
79
+ # 3. Applies ALL release patches sequentially
80
+ # 4. Runs pytest automatically
81
+ # 5. If PASSmerges into release, status "staged"
82
+ # 6. ❌ If FAIL → nothing committed, temp branch deleted
81
83
  ```
82
84
 
83
85
  **Benefits:**
@@ -100,6 +102,7 @@ half_orm dev patch merge
100
102
  - **Semantic versioning**: patch/minor/major increments
101
103
  - **Sequential promotion**: stage → rc → production workflow
102
104
  - **Release candidates**: RC validation before production
105
+ - **Hotfix support**: Reopen last released version for urgent fixes
103
106
  - **Branch cleanup**: Automatic deletion after promotion
104
107
 
105
108
  ### 🚀 Production
@@ -115,8 +118,8 @@ half_orm dev patch merge
115
118
 
116
119
  ### Prerequisites
117
120
 
118
- - **Python 3.9+** required
119
- - **PostgreSQL 12+** recommended
121
+ - **Python**: [Active versions](https://devguide.python.org/versions/) (currently 3.9+)
122
+ - **PostgreSQL**: [Supported versions](https://www.postgresql.org/support/versioning/) (currently 13+)
120
123
  - **Git** for version control
121
124
 
122
125
  ### Install
@@ -138,8 +141,8 @@ half_orm dev --help
138
141
  ### Initialize New Project
139
142
 
140
143
  ```bash
141
- # Create project with database
142
- half_orm dev init myproject --database mydb
144
+ # Create project with database (requires git origin)
145
+ half_orm dev init myproject --database mydb --git-origin git@github.com:user/myproject.git
143
146
  cd myproject
144
147
  ```
145
148
 
@@ -235,6 +238,7 @@ ho-prod (main production branch)
235
238
  ├── 0.17.0-patches.toml # Development (mutable: candidate/staged status)
236
239
  ├── 0.17.0-rc1.txt # Release candidate snapshot (immutable)
237
240
  ├── 0.17.0.txt # Production snapshot (immutable)
241
+ ├── 0.17.0-hotfix1.txt # Hotfix snapshot (immutable)
238
242
  └── 0.18.0-patches.toml # Next version in progress
239
243
  ```
240
244
 
@@ -249,7 +253,7 @@ ho-prod (main production branch)
249
253
  ┌─────────────────────────────────────────────────────────────┐
250
254
  │ DEVELOPMENT WORKFLOW │
251
255
  ├─────────────────────────────────────────────────────────────┤
252
- │ 1. release create <level> Create ho-release/X.Y.Z
256
+ │ 1. release create <level> Create ho-release/X.Y.Z
253
257
  │ 2. patch create <id> Create patch (auto-candidate) │
254
258
  │ 3. patch apply Apply & test changes │
255
259
  │ 4. patch merge Merge into release (TESTS!) │
@@ -263,6 +267,11 @@ ho-prod (main production branch)
263
267
  │ PRODUCTION DEPLOYMENT │
264
268
  │ 7. update Check available releases │
265
269
  │ 8. upgrade Apply on production servers │
270
+ │ │
271
+ │ HOTFIX (urgent production fix) │
272
+ │ 9. release hotfix Reopen last released version │
273
+ │10. patch create/merge Fix and validate │
274
+ │11. release promote hotfix Deploy hotfix │
266
275
  └─────────────────────────────────────────────────────────────┘
267
276
  ```
268
277
 
@@ -273,33 +282,31 @@ ho-prod (main production branch)
273
282
  ### Init & Clone
274
283
 
275
284
  ```bash
276
- # Create new project
277
- half_orm dev init <package_name> --database <db_name>
285
+ # Create new project (requires git origin)
286
+ half_orm dev init <package_name> --database <db_name> --git-origin <url>
278
287
 
279
288
  # Clone existing project
280
289
  half_orm dev clone <git_origin>
281
290
  ```
282
291
 
283
- ### Patch Commands
292
+ ### Check
284
293
 
285
294
  ```bash
286
- # Create new patch (must be on ho-release/* branch)
287
- half_orm dev patch create <patch_id>
288
-
289
- # Apply current patch (must be on ho-patch/* branch)
290
- half_orm dev patch apply
295
+ # Verify and update project configuration
296
+ half_orm dev check
291
297
 
292
- # Merge patch into release (AUTOMATIC VALIDATION!)
293
- # Must be on ho-patch/* branch
294
- half_orm dev patch merge
298
+ # Preview what would be done
299
+ half_orm dev check --dry-run
295
300
  ```
296
301
 
297
- **Tip:** Patch IDs must start with a number (e.g., `123-add-users`). This number automatically closes the corresponding GitHub/GitLab issue #123 when the patch is merged.
302
+ **Note:** This command runs automatically before other commands (git hooks, configuration, stale branches cleanup).
298
303
 
299
304
  ### Release Commands
300
305
 
306
+ A release must be created before creating patches.
307
+
301
308
  ```bash
302
- # Create new release
309
+ # Create new release (must be on ho-prod branch)
303
310
  half_orm dev release create patch # X.Y.(Z+1)
304
311
  half_orm dev release create minor # X.(Y+1).0
305
312
  half_orm dev release create major # (X+1).0.0
@@ -315,6 +322,24 @@ half_orm dev release hotfix # Reopen production version
315
322
  half_orm dev release promote hotfix # Deploy hotfix
316
323
  ```
317
324
 
325
+ ### Patch Commands
326
+
327
+ ```bash
328
+ # Create new patch (must be on ho-release/* branch)
329
+ half_orm dev patch create <patch_id>
330
+
331
+ # Apply current patch (must be on ho-patch/* branch)
332
+ half_orm dev patch apply
333
+
334
+ # Merge patch into release (AUTOMATIC VALIDATION!)
335
+ # Must be on ho-patch/* branch
336
+ half_orm dev patch merge
337
+ ```
338
+
339
+ **Tip:** Patch IDs must start with a number (e.g., `123-add-users`). This number automatically closes the corresponding GitHub/GitLab issue #123 when the patch is merged.
340
+
341
+ **Patch files:** SQL (`.sql`) or Python (`.py`) files in `Patches/<patch_id>/`, executed in lexicographic order.
342
+
318
343
  ### Production Commands
319
344
 
320
345
  ```bash
@@ -328,6 +353,20 @@ half_orm dev upgrade [--to-release X.Y.Z]
328
353
  half_orm dev upgrade --dry-run
329
354
  ```
330
355
 
356
+ ### Data Bootstrap
357
+
358
+ Mark patch files with `-- @HOP:bootstrap` (SQL) or `# @HOP:bootstrap` (Python) to declare reference data:
359
+
360
+ ```sql
361
+ -- @HOP:bootstrap
362
+ INSERT INTO roles (name) VALUES ('admin'), ('user') ON CONFLICT DO NOTHING;
363
+ ```
364
+
365
+ These files are automatically:
366
+ - Copied to `bootstrap/` during `patch merge`
367
+ - Executed during production `upgrade`
368
+ - Tracked in database (each script runs once)
369
+
331
370
  **Note:** Use `half_orm dev <command> --help` for detailed help on each command.
332
371
 
333
372
  ---
@@ -360,47 +399,17 @@ half_orm dev patch merge
360
399
 
361
400
  ---
362
401
 
363
- ## 🎓 Best Practices
364
-
365
- ### Development
366
- ✅ **DO:**
367
- - Write tests FIRST (TDD approach)
368
- - Run `pytest` locally before `patch merge`
369
- - Use descriptive patch IDs: `123-add-user-authentication`
370
- - Keep patches focused (one feature per patch)
371
- - Test patches thoroughly
372
-
373
- **DON'T:**
374
- - Skip writing tests (validation will fail anyway)
375
- - Mix multiple features in one patch
376
- - Bypass test validation (it's there for safety)
377
- - Modify files outside your patch directory
378
-
379
- ### Release Management
380
- ✅ **DO:**
381
- - Trust the automatic test validation system
382
- - Test RC thoroughly before promoting to production
383
- - Use semantic versioning consistently
384
- - Review test failures carefully before retrying
385
-
386
- ❌ **DON'T:**
387
- - Skip RC validation
388
- - Force promote without fixing issues
389
- - Bypass test validation
390
- - Ignore test failures
391
-
392
- ### Production Deployment
393
- ✅ **DO:**
394
- - Always run `update` first to check available releases
395
- - Use `--dry-run` to preview changes
396
- - Verify backups exist before upgrade
397
- - Verify all tests passed in RC before promoting
398
-
399
- ❌ **DON'T:**
400
- - Deploy without testing in RC first
401
- - Skip backup verification
402
- - Promote to production if RC tests failed
403
- - Apply patches directly without releases
402
+ ## 🎓 Development Philosophy
403
+
404
+ half-orm-dev combines **Domain-Driven Design** with **Test-Driven Development**, integrated into Git:
405
+
406
+ 1. **Schema as domain model** - The PostgreSQL schema defines your domain; Python classes are auto-generated
407
+ 2. **Write tests first** - Define expected behavior before implementation
408
+ 3. **Develop in isolation** - Each patch has its own branch and directory
409
+ 4. **Validate automatically** - Tests run during `patch merge`, blocking integration if they fail
410
+ 5. **Deploy with confidence** - Only validated code reaches production
411
+
412
+ This approach ensures that every schema change is tested in the full release context before integration.
404
413
 
405
414
  ---
406
415
 
@@ -463,11 +472,11 @@ git stash
463
472
  git pull origin ho-prod
464
473
  ```
465
474
 
466
- ### Error: "No stage releases found"
475
+ ### Error: "No staged releases found"
467
476
 
468
477
  ```bash
469
- # Solution: Prepare a release first
470
- half_orm dev release new patch
478
+ # Solution: Create a release first
479
+ half_orm dev release create patch
471
480
  ```
472
481
 
473
482
  ### Error: "Active RC exists"
@@ -496,16 +505,6 @@ git checkout ho-patch/123-feature
496
505
  half_orm dev patch merge # Tests will run again
497
506
  ```
498
507
 
499
- ### Error: "Repository is not clean"
500
- ```bash
501
- # Commit or stash changes
502
- git status
503
- git add .
504
- git commit -m "Your message"
505
- # or
506
- git stash
507
- ```
508
-
509
508
  For more troubleshooting, see [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
510
509
 
511
510
  ---
@@ -4,7 +4,7 @@
4
4
 
5
5
  > **Please report any issues at [GitHub Issues](https://github.com/half-orm/half-orm-dev/issues)**
6
6
 
7
- **Git-centric patch management and database versioning for half-orm projects**
7
+ **Git-centric patch management and PostgreSQL database versioning for half-orm projects**
8
8
 
9
9
  [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
10
10
  [![License: GPLv3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
@@ -22,6 +22,7 @@ Modern development workflow for PostgreSQL databases with automatic code generat
22
22
  - **Git-centric workflow**: Patches stored in Git branches with semantic versioning
23
23
  - **Test-Driven Development**: **Automatic validation** - tests run before integration, patches blocked if tests fail
24
24
  - **Code generation**: Python classes auto-generated from schema changes
25
+ - **Data bootstrapping**: Initialize reference data and configurations with tracked scripts
25
26
  - **Safe deployments**: Sequential releases with automatic backups and validation
26
27
  - **Team collaboration**: Distributed locks, branch management, conflict prevention
27
28
  - **Cloud-friendly**: No superuser privileges required (works on AWS RDS, Azure, GCP)
@@ -43,10 +44,11 @@ half_orm dev patch merge
43
44
 
44
45
  # Behind the scenes:
45
46
  # 1. Creates temporary validation branch
46
- # 2. Merges ALL patches in release context
47
- # 3. Runs pytest automatically
48
- # 4. If PASS → merges into release, status → "staged"
49
- # 5. If FAILnothing committed, temp branch deleted
47
+ # 2. Restores database from production schema
48
+ # 3. Applies ALL release patches sequentially
49
+ # 4. Runs pytest automatically
50
+ # 5. If PASSmerges into release, status "staged"
51
+ # 6. ❌ If FAIL → nothing committed, temp branch deleted
50
52
  ```
51
53
 
52
54
  **Benefits:**
@@ -69,6 +71,7 @@ half_orm dev patch merge
69
71
  - **Semantic versioning**: patch/minor/major increments
70
72
  - **Sequential promotion**: stage → rc → production workflow
71
73
  - **Release candidates**: RC validation before production
74
+ - **Hotfix support**: Reopen last released version for urgent fixes
72
75
  - **Branch cleanup**: Automatic deletion after promotion
73
76
 
74
77
  ### 🚀 Production
@@ -84,8 +87,8 @@ half_orm dev patch merge
84
87
 
85
88
  ### Prerequisites
86
89
 
87
- - **Python 3.9+** required
88
- - **PostgreSQL 12+** recommended
90
+ - **Python**: [Active versions](https://devguide.python.org/versions/) (currently 3.9+)
91
+ - **PostgreSQL**: [Supported versions](https://www.postgresql.org/support/versioning/) (currently 13+)
89
92
  - **Git** for version control
90
93
 
91
94
  ### Install
@@ -107,8 +110,8 @@ half_orm dev --help
107
110
  ### Initialize New Project
108
111
 
109
112
  ```bash
110
- # Create project with database
111
- half_orm dev init myproject --database mydb
113
+ # Create project with database (requires git origin)
114
+ half_orm dev init myproject --database mydb --git-origin git@github.com:user/myproject.git
112
115
  cd myproject
113
116
  ```
114
117
 
@@ -204,6 +207,7 @@ ho-prod (main production branch)
204
207
  ├── 0.17.0-patches.toml # Development (mutable: candidate/staged status)
205
208
  ├── 0.17.0-rc1.txt # Release candidate snapshot (immutable)
206
209
  ├── 0.17.0.txt # Production snapshot (immutable)
210
+ ├── 0.17.0-hotfix1.txt # Hotfix snapshot (immutable)
207
211
  └── 0.18.0-patches.toml # Next version in progress
208
212
  ```
209
213
 
@@ -218,7 +222,7 @@ ho-prod (main production branch)
218
222
  ┌─────────────────────────────────────────────────────────────┐
219
223
  │ DEVELOPMENT WORKFLOW │
220
224
  ├─────────────────────────────────────────────────────────────┤
221
- │ 1. release create <level> Create ho-release/X.Y.Z
225
+ │ 1. release create <level> Create ho-release/X.Y.Z
222
226
  │ 2. patch create <id> Create patch (auto-candidate) │
223
227
  │ 3. patch apply Apply & test changes │
224
228
  │ 4. patch merge Merge into release (TESTS!) │
@@ -232,6 +236,11 @@ ho-prod (main production branch)
232
236
  │ PRODUCTION DEPLOYMENT │
233
237
  │ 7. update Check available releases │
234
238
  │ 8. upgrade Apply on production servers │
239
+ │ │
240
+ │ HOTFIX (urgent production fix) │
241
+ │ 9. release hotfix Reopen last released version │
242
+ │10. patch create/merge Fix and validate │
243
+ │11. release promote hotfix Deploy hotfix │
235
244
  └─────────────────────────────────────────────────────────────┘
236
245
  ```
237
246
 
@@ -242,33 +251,31 @@ ho-prod (main production branch)
242
251
  ### Init & Clone
243
252
 
244
253
  ```bash
245
- # Create new project
246
- half_orm dev init <package_name> --database <db_name>
254
+ # Create new project (requires git origin)
255
+ half_orm dev init <package_name> --database <db_name> --git-origin <url>
247
256
 
248
257
  # Clone existing project
249
258
  half_orm dev clone <git_origin>
250
259
  ```
251
260
 
252
- ### Patch Commands
261
+ ### Check
253
262
 
254
263
  ```bash
255
- # Create new patch (must be on ho-release/* branch)
256
- half_orm dev patch create <patch_id>
257
-
258
- # Apply current patch (must be on ho-patch/* branch)
259
- half_orm dev patch apply
264
+ # Verify and update project configuration
265
+ half_orm dev check
260
266
 
261
- # Merge patch into release (AUTOMATIC VALIDATION!)
262
- # Must be on ho-patch/* branch
263
- half_orm dev patch merge
267
+ # Preview what would be done
268
+ half_orm dev check --dry-run
264
269
  ```
265
270
 
266
- **Tip:** Patch IDs must start with a number (e.g., `123-add-users`). This number automatically closes the corresponding GitHub/GitLab issue #123 when the patch is merged.
271
+ **Note:** This command runs automatically before other commands (git hooks, configuration, stale branches cleanup).
267
272
 
268
273
  ### Release Commands
269
274
 
275
+ A release must be created before creating patches.
276
+
270
277
  ```bash
271
- # Create new release
278
+ # Create new release (must be on ho-prod branch)
272
279
  half_orm dev release create patch # X.Y.(Z+1)
273
280
  half_orm dev release create minor # X.(Y+1).0
274
281
  half_orm dev release create major # (X+1).0.0
@@ -284,6 +291,24 @@ half_orm dev release hotfix # Reopen production version
284
291
  half_orm dev release promote hotfix # Deploy hotfix
285
292
  ```
286
293
 
294
+ ### Patch Commands
295
+
296
+ ```bash
297
+ # Create new patch (must be on ho-release/* branch)
298
+ half_orm dev patch create <patch_id>
299
+
300
+ # Apply current patch (must be on ho-patch/* branch)
301
+ half_orm dev patch apply
302
+
303
+ # Merge patch into release (AUTOMATIC VALIDATION!)
304
+ # Must be on ho-patch/* branch
305
+ half_orm dev patch merge
306
+ ```
307
+
308
+ **Tip:** Patch IDs must start with a number (e.g., `123-add-users`). This number automatically closes the corresponding GitHub/GitLab issue #123 when the patch is merged.
309
+
310
+ **Patch files:** SQL (`.sql`) or Python (`.py`) files in `Patches/<patch_id>/`, executed in lexicographic order.
311
+
287
312
  ### Production Commands
288
313
 
289
314
  ```bash
@@ -297,6 +322,20 @@ half_orm dev upgrade [--to-release X.Y.Z]
297
322
  half_orm dev upgrade --dry-run
298
323
  ```
299
324
 
325
+ ### Data Bootstrap
326
+
327
+ Mark patch files with `-- @HOP:bootstrap` (SQL) or `# @HOP:bootstrap` (Python) to declare reference data:
328
+
329
+ ```sql
330
+ -- @HOP:bootstrap
331
+ INSERT INTO roles (name) VALUES ('admin'), ('user') ON CONFLICT DO NOTHING;
332
+ ```
333
+
334
+ These files are automatically:
335
+ - Copied to `bootstrap/` during `patch merge`
336
+ - Executed during production `upgrade`
337
+ - Tracked in database (each script runs once)
338
+
300
339
  **Note:** Use `half_orm dev <command> --help` for detailed help on each command.
301
340
 
302
341
  ---
@@ -329,47 +368,17 @@ half_orm dev patch merge
329
368
 
330
369
  ---
331
370
 
332
- ## 🎓 Best Practices
333
-
334
- ### Development
335
- ✅ **DO:**
336
- - Write tests FIRST (TDD approach)
337
- - Run `pytest` locally before `patch merge`
338
- - Use descriptive patch IDs: `123-add-user-authentication`
339
- - Keep patches focused (one feature per patch)
340
- - Test patches thoroughly
341
-
342
- **DON'T:**
343
- - Skip writing tests (validation will fail anyway)
344
- - Mix multiple features in one patch
345
- - Bypass test validation (it's there for safety)
346
- - Modify files outside your patch directory
347
-
348
- ### Release Management
349
- ✅ **DO:**
350
- - Trust the automatic test validation system
351
- - Test RC thoroughly before promoting to production
352
- - Use semantic versioning consistently
353
- - Review test failures carefully before retrying
354
-
355
- ❌ **DON'T:**
356
- - Skip RC validation
357
- - Force promote without fixing issues
358
- - Bypass test validation
359
- - Ignore test failures
360
-
361
- ### Production Deployment
362
- ✅ **DO:**
363
- - Always run `update` first to check available releases
364
- - Use `--dry-run` to preview changes
365
- - Verify backups exist before upgrade
366
- - Verify all tests passed in RC before promoting
367
-
368
- ❌ **DON'T:**
369
- - Deploy without testing in RC first
370
- - Skip backup verification
371
- - Promote to production if RC tests failed
372
- - Apply patches directly without releases
371
+ ## 🎓 Development Philosophy
372
+
373
+ half-orm-dev combines **Domain-Driven Design** with **Test-Driven Development**, integrated into Git:
374
+
375
+ 1. **Schema as domain model** - The PostgreSQL schema defines your domain; Python classes are auto-generated
376
+ 2. **Write tests first** - Define expected behavior before implementation
377
+ 3. **Develop in isolation** - Each patch has its own branch and directory
378
+ 4. **Validate automatically** - Tests run during `patch merge`, blocking integration if they fail
379
+ 5. **Deploy with confidence** - Only validated code reaches production
380
+
381
+ This approach ensures that every schema change is tested in the full release context before integration.
373
382
 
374
383
  ---
375
384
 
@@ -432,11 +441,11 @@ git stash
432
441
  git pull origin ho-prod
433
442
  ```
434
443
 
435
- ### Error: "No stage releases found"
444
+ ### Error: "No staged releases found"
436
445
 
437
446
  ```bash
438
- # Solution: Prepare a release first
439
- half_orm dev release new patch
447
+ # Solution: Create a release first
448
+ half_orm dev release create patch
440
449
  ```
441
450
 
442
451
  ### Error: "Active RC exists"
@@ -465,16 +474,6 @@ git checkout ho-patch/123-feature
465
474
  half_orm dev patch merge # Tests will run again
466
475
  ```
467
476
 
468
- ### Error: "Repository is not clean"
469
- ```bash
470
- # Commit or stash changes
471
- git status
472
- git add .
473
- git commit -m "Your message"
474
- # or
475
- git stash
476
- ```
477
-
478
477
  For more troubleshooting, see [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
479
478
 
480
479
  ---
@@ -925,7 +925,7 @@ class HGit:
925
925
  match = re.search(r'-(\d+)$', existing_locks[0])
926
926
  if match:
927
927
  lock_timestamp_ms = int(match.group(1))
928
- lock_time = datetime.utcfromtimestamp(lock_timestamp_ms / 1000.0)
928
+ lock_time = datetime.fromtimestamp(lock_timestamp_ms / 1000.0, tz=timezone.utc)
929
929
  current_time = datetime.now(timezone.utc)
930
930
 
931
931
  # Check if lock is stale
@@ -302,6 +302,9 @@ class MigrationManager:
302
302
  self._repo._Repo__config.hop_version = target_version
303
303
  self._repo._Repo__config.write()
304
304
 
305
+ # Update half_orm_dev version in pyproject.toml
306
+ self._update_pyproject_dependency_version(target_version)
307
+
305
308
  # Create Git commit if requested
306
309
  if create_commit and self._repo.hgit:
307
310
  try:
@@ -367,6 +370,49 @@ class MigrationManager:
367
370
 
368
371
  return '\n'.join(lines)
369
372
 
373
+ def _update_pyproject_dependency_version(self, target_version: str) -> None:
374
+ """
375
+ Update half_orm_dev version in pyproject.toml.
376
+
377
+ This ensures the project's dependency on half_orm_dev always matches
378
+ the current tool version after each migration.
379
+
380
+ Handles both == and >= version specifiers.
381
+
382
+ Args:
383
+ target_version: New version to set for half_orm_dev dependency
384
+ """
385
+ import re
386
+
387
+ pyproject_path = Path(self._repo.base_dir) / "pyproject.toml"
388
+
389
+ if not pyproject_path.exists():
390
+ return
391
+
392
+ try:
393
+ content = pyproject_path.read_text()
394
+
395
+ # Only update if half_orm_dev dependency exists (== or >=)
396
+ if 'half_orm_dev==' not in content and 'half_orm_dev>=' not in content:
397
+ return
398
+
399
+ # Update the version (handles both == and >=)
400
+ new_content = re.sub(
401
+ r'half_orm_dev[>=]=[\d.a-zA-Z-]+',
402
+ f'half_orm_dev=={target_version}',
403
+ content
404
+ )
405
+
406
+ if new_content != content:
407
+ pyproject_path.write_text(new_content)
408
+ if self._repo.hgit:
409
+ self._repo.hgit.add(str(pyproject_path))
410
+ print(f" Updated pyproject.toml: half_orm_dev=={target_version}")
411
+
412
+ except Exception as e:
413
+ # Non-critical - don't fail migration
414
+ print(f" Warning: Could not update pyproject.toml: {e}")
415
+
370
416
  def check_migration_needed(self, current_tool_version: str) -> bool:
371
417
  """
372
418
  Check if migration is needed.