milpa-core 0.3.1__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 (285) hide show
  1. milpa_core-0.3.1/.dockerignore +17 -0
  2. milpa_core-0.3.1/.env.example +118 -0
  3. milpa_core-0.3.1/.github/workflows/ci.yml +65 -0
  4. milpa_core-0.3.1/.github/workflows/release.yml +54 -0
  5. milpa_core-0.3.1/.gitignore +45 -0
  6. milpa_core-0.3.1/CHANGELOG.md +146 -0
  7. milpa_core-0.3.1/CODE_OF_CONDUCT.md +58 -0
  8. milpa_core-0.3.1/CONTRIBUTING.md +148 -0
  9. milpa_core-0.3.1/LICENSE +21 -0
  10. milpa_core-0.3.1/PKG-INFO +246 -0
  11. milpa_core-0.3.1/README.md +192 -0
  12. milpa_core-0.3.1/Tests/Core/Auth/test_Auth.py +136 -0
  13. milpa_core-0.3.1/Tests/Core/Auth/test_Authorization.py +165 -0
  14. milpa_core-0.3.1/Tests/Core/Auth/test_Hash.py +23 -0
  15. milpa_core-0.3.1/Tests/Core/Auth/test_PassportGuard.py +77 -0
  16. milpa_core-0.3.1/Tests/Core/Auth/test_Policy.py +54 -0
  17. milpa_core-0.3.1/Tests/Core/Auth/test_SessionGuard.py +80 -0
  18. milpa_core-0.3.1/Tests/Core/CeleryApp/test_Dispatch.py +28 -0
  19. milpa_core-0.3.1/Tests/Core/CeleryApp/test_Retry.py +41 -0
  20. milpa_core-0.3.1/Tests/Core/Config/test_BrokerSettings.py +30 -0
  21. milpa_core-0.3.1/Tests/Core/Config/test_CookieSettings.py +30 -0
  22. milpa_core-0.3.1/Tests/Core/Console/test_CliErrorBoundary.py +20 -0
  23. milpa_core-0.3.1/Tests/Core/Console/test_Console.py +138 -0
  24. milpa_core-0.3.1/Tests/Core/Console/test_DiscoveryLoud.py +43 -0
  25. milpa_core-0.3.1/Tests/Core/Console/test_FormatCommandList.py +50 -0
  26. milpa_core-0.3.1/Tests/Core/Console/test_JornalLauncher.py +39 -0
  27. milpa_core-0.3.1/Tests/Core/Console/test_LauncherCommands.py +62 -0
  28. milpa_core-0.3.1/Tests/Core/Console/test_MakeWritesToAppDir.py +158 -0
  29. milpa_core-0.3.1/Tests/Core/Console/test_NewCommands.py +77 -0
  30. milpa_core-0.3.1/Tests/Core/Console/test_ScheduleRunCommand.py +85 -0
  31. milpa_core-0.3.1/Tests/Core/Cron/test_Schedule.py +66 -0
  32. milpa_core-0.3.1/Tests/Core/Database/test_Factory.py +90 -0
  33. milpa_core-0.3.1/Tests/Core/Database/test_Filtering.py +82 -0
  34. milpa_core-0.3.1/Tests/Core/Database/test_Migrations.py +84 -0
  35. milpa_core-0.3.1/Tests/Core/Database/test_Repository.py +179 -0
  36. milpa_core-0.3.1/Tests/Core/Database/test_Seeder.py +46 -0
  37. milpa_core-0.3.1/Tests/Core/Database/test_Session.py +39 -0
  38. milpa_core-0.3.1/Tests/Core/Database/test_Transactional.py +98 -0
  39. milpa_core-0.3.1/Tests/Core/Events/test_EventDispatch.py +93 -0
  40. milpa_core-0.3.1/Tests/Core/Events/test_Observer.py +34 -0
  41. milpa_core-0.3.1/Tests/Core/Http/test_Csrf.py +74 -0
  42. milpa_core-0.3.1/Tests/Core/Http/test_ExceptionHandler.py +123 -0
  43. milpa_core-0.3.1/Tests/Core/Http/test_Middleware.py +47 -0
  44. milpa_core-0.3.1/Tests/Core/Http/test_RateLimit.py +56 -0
  45. milpa_core-0.3.1/Tests/Core/Http/test_Routing.py +117 -0
  46. milpa_core-0.3.1/Tests/Core/Http/test_SecurityHeaders.py +86 -0
  47. milpa_core-0.3.1/Tests/Core/Jobs/test_Jobs.py +61 -0
  48. milpa_core-0.3.1/Tests/Core/Mail/test_Mail.py +65 -0
  49. milpa_core-0.3.1/Tests/Core/Mail/test_MailDriver.py +39 -0
  50. milpa_core-0.3.1/Tests/Core/Mail/test_Mailable.py +55 -0
  51. milpa_core-0.3.1/Tests/Core/Mail/test_Mailer.py +174 -0
  52. milpa_core-0.3.1/Tests/Core/Mail/test_MailerDispatch.py +50 -0
  53. milpa_core-0.3.1/Tests/Core/Mail/test_Tasks.py +120 -0
  54. milpa_core-0.3.1/Tests/Core/Mediator/test_Mediator.py +54 -0
  55. milpa_core-0.3.1/Tests/Core/Pipeline/test_Pipeline.py +43 -0
  56. milpa_core-0.3.1/Tests/Core/Translate/test_AcceptLanguage.py +20 -0
  57. milpa_core-0.3.1/Tests/Core/Translate/test_I18n.py +164 -0
  58. milpa_core-0.3.1/Tests/Core/View/test_Negotiation.py +51 -0
  59. milpa_core-0.3.1/Tests/Core/View/test_TemplateEngine.py +109 -0
  60. milpa_core-0.3.1/Tests/Core/test_Clock.py +20 -0
  61. milpa_core-0.3.1/Tests/Core/test_Cron.py +57 -0
  62. milpa_core-0.3.1/Tests/Core/test_FrameworkIsGeneric.py +36 -0
  63. milpa_core-0.3.1/Tests/Core/test_ModelDiscovery.py +20 -0
  64. milpa_core-0.3.1/Tests/Modules/Demo/test_DemoBuildingBlocks.py +126 -0
  65. milpa_core-0.3.1/Tests/Modules/Demo/test_DemoFlows.py +100 -0
  66. milpa_core-0.3.1/Tests/conftest.py +18 -0
  67. milpa_core-0.3.1/docker-compose.yml +42 -0
  68. milpa_core-0.3.1/documentation/01-introduccion.md +83 -0
  69. milpa_core-0.3.1/documentation/02-instalacion.md +93 -0
  70. milpa_core-0.3.1/documentation/03-configuracion.md +127 -0
  71. milpa_core-0.3.1/documentation/04-estructura-directorios.md +85 -0
  72. milpa_core-0.3.1/documentation/05-ciclo-de-vida.md +100 -0
  73. milpa_core-0.3.1/documentation/06-monolito-modular.md +103 -0
  74. milpa_core-0.3.1/documentation/07-rutas-y-controladores.md +188 -0
  75. milpa_core-0.3.1/documentation/08-consola-jornal.md +110 -0
  76. milpa_core-0.3.1/documentation/09-vistas.md +92 -0
  77. milpa_core-0.3.1/documentation/10-correo.md +173 -0
  78. milpa_core-0.3.1/documentation/11-colas-y-tareas.md +154 -0
  79. milpa_core-0.3.1/documentation/12-programacion-cron.md +147 -0
  80. milpa_core-0.3.1/documentation/13-localizacion-i18n.md +118 -0
  81. milpa_core-0.3.1/documentation/14-logging.md +53 -0
  82. milpa_core-0.3.1/documentation/15-autenticacion.md +174 -0
  83. milpa_core-0.3.1/documentation/16-base-de-datos.md +133 -0
  84. milpa_core-0.3.1/documentation/17-modelos.md +109 -0
  85. milpa_core-0.3.1/documentation/18-repositorios-y-transacciones.md +192 -0
  86. milpa_core-0.3.1/documentation/19-eventos-y-observers.md +250 -0
  87. milpa_core-0.3.1/documentation/20-mediator.md +265 -0
  88. milpa_core-0.3.1/documentation/21-pipeline.md +221 -0
  89. milpa_core-0.3.1/documentation/22-jobs.md +174 -0
  90. milpa_core-0.3.1/documentation/23-versionado-api.md +194 -0
  91. milpa_core-0.3.1/documentation/24-rate-limiting.md +181 -0
  92. milpa_core-0.3.1/documentation/25-filtrado-y-paginacion.md +294 -0
  93. milpa_core-0.3.1/documentation/26-negociacion-de-contenido.md +174 -0
  94. milpa_core-0.3.1/documentation/27-serializadores.md +207 -0
  95. milpa_core-0.3.1/documentation/28-errores-y-rfc9457.md +339 -0
  96. milpa_core-0.3.1/documentation/README.md +67 -0
  97. milpa_core-0.3.1/jornal +18 -0
  98. milpa_core-0.3.1/logs/.gitkeep +0 -0
  99. milpa_core-0.3.1/migrations/env.py +50 -0
  100. milpa_core-0.3.1/migrations/script.py.mako +27 -0
  101. milpa_core-0.3.1/migrations/versions/.gitkeep +0 -0
  102. milpa_core-0.3.1/migrations/versions/a7c1d9e2f4b8_add_archived_to_notes.py +29 -0
  103. milpa_core-0.3.1/migrations/versions/c35b0c89ce97_demo_users_and_notes.py +55 -0
  104. milpa_core-0.3.1/mkdocs.yml +93 -0
  105. milpa_core-0.3.1/pyproject.toml +173 -0
  106. milpa_core-0.3.1/src/milpa/Core/Auth/Auth.py +113 -0
  107. milpa_core-0.3.1/src/milpa/Core/Auth/Authorization.py +147 -0
  108. milpa_core-0.3.1/src/milpa/Core/Auth/Contracts.py +62 -0
  109. milpa_core-0.3.1/src/milpa/Core/Auth/Guards.py +98 -0
  110. milpa_core-0.3.1/src/milpa/Core/Auth/Hash.py +38 -0
  111. milpa_core-0.3.1/src/milpa/Core/Auth/Passport.py +95 -0
  112. milpa_core-0.3.1/src/milpa/Core/Auth/Providers.py +69 -0
  113. milpa_core-0.3.1/src/milpa/Core/Auth/Tokens.py +36 -0
  114. milpa_core-0.3.1/src/milpa/Core/Auth/__init__.py +52 -0
  115. milpa_core-0.3.1/src/milpa/Core/CeleryApp/CeleryApp.py +57 -0
  116. milpa_core-0.3.1/src/milpa/Core/CeleryApp/Dispatch.py +47 -0
  117. milpa_core-0.3.1/src/milpa/Core/CeleryApp/Retry.py +67 -0
  118. milpa_core-0.3.1/src/milpa/Core/CeleryApp/__init__.py +11 -0
  119. milpa_core-0.3.1/src/milpa/Core/Clock/Clock.py +40 -0
  120. milpa_core-0.3.1/src/milpa/Core/Clock/__init__.py +11 -0
  121. milpa_core-0.3.1/src/milpa/Core/Config/Settings.py +262 -0
  122. milpa_core-0.3.1/src/milpa/Core/Config/__init__.py +5 -0
  123. milpa_core-0.3.1/src/milpa/Core/Console/Cli.py +147 -0
  124. milpa_core-0.3.1/src/milpa/Core/Console/Commands/DbCommands.py +27 -0
  125. milpa_core-0.3.1/src/milpa/Core/Console/Commands/MakeCommands.py +418 -0
  126. milpa_core-0.3.1/src/milpa/Core/Console/Commands/MigrateCommands.py +72 -0
  127. milpa_core-0.3.1/src/milpa/Core/Console/Commands/QueueWorkCommand.py +44 -0
  128. milpa_core-0.3.1/src/milpa/Core/Console/Commands/RouteCommands.py +33 -0
  129. milpa_core-0.3.1/src/milpa/Core/Console/Commands/ScheduleRunCommand.py +49 -0
  130. milpa_core-0.3.1/src/milpa/Core/Console/Commands/ScheduleWorkCommand.py +33 -0
  131. milpa_core-0.3.1/src/milpa/Core/Console/Commands/SeedCommands.py +33 -0
  132. milpa_core-0.3.1/src/milpa/Core/Console/Commands/__init__.py +7 -0
  133. milpa_core-0.3.1/src/milpa/Core/Console/Console.py +171 -0
  134. milpa_core-0.3.1/src/milpa/Core/Console/Scaffold.py +93 -0
  135. milpa_core-0.3.1/src/milpa/Core/Console/__init__.py +29 -0
  136. milpa_core-0.3.1/src/milpa/Core/Cron/Cron.py +188 -0
  137. milpa_core-0.3.1/src/milpa/Core/Cron/Schedule.py +95 -0
  138. milpa_core-0.3.1/src/milpa/Core/Cron/__init__.py +48 -0
  139. milpa_core-0.3.1/src/milpa/Core/Database/Base.py +25 -0
  140. milpa_core-0.3.1/src/milpa/Core/Database/Factory.py +59 -0
  141. milpa_core-0.3.1/src/milpa/Core/Database/Faker.py +28 -0
  142. milpa_core-0.3.1/src/milpa/Core/Database/Filtering.py +101 -0
  143. milpa_core-0.3.1/src/milpa/Core/Database/Migrations.py +57 -0
  144. milpa_core-0.3.1/src/milpa/Core/Database/Repository.py +192 -0
  145. milpa_core-0.3.1/src/milpa/Core/Database/Seeder.py +32 -0
  146. milpa_core-0.3.1/src/milpa/Core/Database/Session.py +87 -0
  147. milpa_core-0.3.1/src/milpa/Core/Database/SoftDelete.py +25 -0
  148. milpa_core-0.3.1/src/milpa/Core/Database/Timestamp.py +27 -0
  149. milpa_core-0.3.1/src/milpa/Core/Database/Transactional.py +110 -0
  150. milpa_core-0.3.1/src/milpa/Core/Database/__init__.py +27 -0
  151. milpa_core-0.3.1/src/milpa/Core/Discovery.py +50 -0
  152. milpa_core-0.3.1/src/milpa/Core/Errors/Errors.py +137 -0
  153. milpa_core-0.3.1/src/milpa/Core/Errors/__init__.py +28 -0
  154. milpa_core-0.3.1/src/milpa/Core/Events/Dispatch.py +45 -0
  155. milpa_core-0.3.1/src/milpa/Core/Events/Observer.py +43 -0
  156. milpa_core-0.3.1/src/milpa/Core/Events/Tasks.py +54 -0
  157. milpa_core-0.3.1/src/milpa/Core/Events/__init__.py +19 -0
  158. milpa_core-0.3.1/src/milpa/Core/Http/Csrf.py +107 -0
  159. milpa_core-0.3.1/src/milpa/Core/Http/ExceptionHandler.py +123 -0
  160. milpa_core-0.3.1/src/milpa/Core/Http/Http.py +125 -0
  161. milpa_core-0.3.1/src/milpa/Core/Http/Middleware.py +91 -0
  162. milpa_core-0.3.1/src/milpa/Core/Http/ProblemDetails.py +49 -0
  163. milpa_core-0.3.1/src/milpa/Core/Http/RateLimit.py +96 -0
  164. milpa_core-0.3.1/src/milpa/Core/Http/Routing.py +165 -0
  165. milpa_core-0.3.1/src/milpa/Core/Http/SecurityHeaders.py +42 -0
  166. milpa_core-0.3.1/src/milpa/Core/Http/__init__.py +12 -0
  167. milpa_core-0.3.1/src/milpa/Core/Jobs/Jobs.py +87 -0
  168. milpa_core-0.3.1/src/milpa/Core/Jobs/__init__.py +10 -0
  169. milpa_core-0.3.1/src/milpa/Core/Logging/Logging.py +88 -0
  170. milpa_core-0.3.1/src/milpa/Core/Logging/__init__.py +10 -0
  171. milpa_core-0.3.1/src/milpa/Core/Mail/Mail.py +56 -0
  172. milpa_core-0.3.1/src/milpa/Core/Mail/Mailable.py +91 -0
  173. milpa_core-0.3.1/src/milpa/Core/Mail/Mailer.py +285 -0
  174. milpa_core-0.3.1/src/milpa/Core/Mail/Tasks.py +143 -0
  175. milpa_core-0.3.1/src/milpa/Core/Mail/__init__.py +20 -0
  176. milpa_core-0.3.1/src/milpa/Core/Mediator/Mediator.py +62 -0
  177. milpa_core-0.3.1/src/milpa/Core/Mediator/__init__.py +20 -0
  178. milpa_core-0.3.1/src/milpa/Core/Pipeline/Pipeline.py +60 -0
  179. milpa_core-0.3.1/src/milpa/Core/Pipeline/__init__.py +10 -0
  180. milpa_core-0.3.1/src/milpa/Core/Registry/Registry.py +213 -0
  181. milpa_core-0.3.1/src/milpa/Core/Registry/__init__.py +36 -0
  182. milpa_core-0.3.1/src/milpa/Core/Translate/I18n.py +171 -0
  183. milpa_core-0.3.1/src/milpa/Core/Translate/__init__.py +14 -0
  184. milpa_core-0.3.1/src/milpa/Core/View/TemplateEngine.py +149 -0
  185. milpa_core-0.3.1/src/milpa/Core/View/View.py +82 -0
  186. milpa_core-0.3.1/src/milpa/Core/View/__init__.py +10 -0
  187. milpa_core-0.3.1/src/milpa/Core/__init__.py +0 -0
  188. milpa_core-0.3.1/src/milpa/Dictionaries/__init__.py +11 -0
  189. milpa_core-0.3.1/src/milpa/Models/Note.py +20 -0
  190. milpa_core-0.3.1/src/milpa/Models/User.py +22 -0
  191. milpa_core-0.3.1/src/milpa/Models/__init__.py +22 -0
  192. milpa_core-0.3.1/src/milpa/Modules/Demo/Commands.py +17 -0
  193. milpa_core-0.3.1/src/milpa/Modules/Demo/Console/Commands/ArchiveNoteCommand.py +26 -0
  194. milpa_core-0.3.1/src/milpa/Modules/Demo/Console/Commands/__init__.py +1 -0
  195. milpa_core-0.3.1/src/milpa/Modules/Demo/Console/__init__.py +1 -0
  196. milpa_core-0.3.1/src/milpa/Modules/Demo/Crons/DailyDigestCron.py +21 -0
  197. milpa_core-0.3.1/src/milpa/Modules/Demo/Crons/__init__.py +3 -0
  198. milpa_core-0.3.1/src/milpa/Modules/Demo/Events.py +36 -0
  199. milpa_core-0.3.1/src/milpa/Modules/Demo/Factories/__init__.py +7 -0
  200. milpa_core-0.3.1/src/milpa/Modules/Demo/Factories/factories.py +38 -0
  201. milpa_core-0.3.1/src/milpa/Modules/Demo/Handlers/ArchiveNoteHandler.py +35 -0
  202. milpa_core-0.3.1/src/milpa/Modules/Demo/Handlers/__init__.py +2 -0
  203. milpa_core-0.3.1/src/milpa/Modules/Demo/Http/ApiController.py +157 -0
  204. milpa_core-0.3.1/src/milpa/Modules/Demo/Http/ReportsController.py +46 -0
  205. milpa_core-0.3.1/src/milpa/Modules/Demo/Http/WebController.py +233 -0
  206. milpa_core-0.3.1/src/milpa/Modules/Demo/Http/__init__.py +1 -0
  207. milpa_core-0.3.1/src/milpa/Modules/Demo/Jobs/ExportNotesJob.py +21 -0
  208. milpa_core-0.3.1/src/milpa/Modules/Demo/Jobs/__init__.py +2 -0
  209. milpa_core-0.3.1/src/milpa/Modules/Demo/Mail/DemoMailable.py +40 -0
  210. milpa_core-0.3.1/src/milpa/Modules/Demo/Mail/NewUserAdminMailable.py +26 -0
  211. milpa_core-0.3.1/src/milpa/Modules/Demo/Mail/NoteCreatedMailable.py +31 -0
  212. milpa_core-0.3.1/src/milpa/Modules/Demo/Mail/ShareNoteMailable.py +27 -0
  213. milpa_core-0.3.1/src/milpa/Modules/Demo/Mail/__init__.py +2 -0
  214. milpa_core-0.3.1/src/milpa/Modules/Demo/Observers/NotifyAdminOnUserRegistered.py +27 -0
  215. milpa_core-0.3.1/src/milpa/Modules/Demo/Observers/NotifyOwnerOnNoteCreated.py +20 -0
  216. milpa_core-0.3.1/src/milpa/Modules/Demo/Observers/__init__.py +3 -0
  217. milpa_core-0.3.1/src/milpa/Modules/Demo/Pipes/CleanContent.py +38 -0
  218. milpa_core-0.3.1/src/milpa/Modules/Demo/Pipes/__init__.py +2 -0
  219. milpa_core-0.3.1/src/milpa/Modules/Demo/Policies.py +29 -0
  220. milpa_core-0.3.1/src/milpa/Modules/Demo/Repositories/NoteRepository.py +20 -0
  221. milpa_core-0.3.1/src/milpa/Modules/Demo/Repositories/UserRepository.py +15 -0
  222. milpa_core-0.3.1/src/milpa/Modules/Demo/Repositories/__init__.py +1 -0
  223. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Lang/demo/NoteCreated.en.yml +4 -0
  224. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Lang/demo/NoteCreated.es.yml +4 -0
  225. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Static/css/app.css +99 -0
  226. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Static/favicon.ico +0 -0
  227. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Static/logo.png +0 -0
  228. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/_notes_results.html.j2 +32 -0
  229. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/_users_results.html.j2 +32 -0
  230. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/admin_users.html.j2 +17 -0
  231. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/dashboard.html.j2 +30 -0
  232. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/emails/new_user_admin.html.j2 +10 -0
  233. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/emails/note_created.html.j2 +6 -0
  234. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/emails/share_note.html.j2 +7 -0
  235. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/forbidden.html.j2 +10 -0
  236. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/layout.html.j2 +59 -0
  237. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/login.html.j2 +53 -0
  238. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/notes.html.j2 +24 -0
  239. milpa_core-0.3.1/src/milpa/Modules/Demo/Resources/Views/register.html.j2 +49 -0
  240. milpa_core-0.3.1/src/milpa/Modules/Demo/Seeders/DemoSeeder.py +38 -0
  241. milpa_core-0.3.1/src/milpa/Modules/Demo/Seeders/__init__.py +1 -0
  242. milpa_core-0.3.1/src/milpa/Modules/Demo/Serializers.py +60 -0
  243. milpa_core-0.3.1/src/milpa/Modules/Demo/Services/NoteService.py +53 -0
  244. milpa_core-0.3.1/src/milpa/Modules/Demo/Services/UserService.py +25 -0
  245. milpa_core-0.3.1/src/milpa/Modules/Demo/Services/__init__.py +1 -0
  246. milpa_core-0.3.1/src/milpa/Modules/Demo/__init__.py +6 -0
  247. milpa_core-0.3.1/src/milpa/Modules/__init__.py +0 -0
  248. milpa_core-0.3.1/src/milpa/Resources/Files/Emails/sample.pdf +0 -0
  249. milpa_core-0.3.1/src/milpa/Resources/Images/Emails/logo.png +0 -0
  250. milpa_core-0.3.1/src/milpa/Resources/Lang/Emails/master.en.yml +14 -0
  251. milpa_core-0.3.1/src/milpa/Resources/Lang/Emails/master.es.yml +15 -0
  252. milpa_core-0.3.1/src/milpa/Resources/Lang/Emails/mastersigned.en.yml +35 -0
  253. milpa_core-0.3.1/src/milpa/Resources/Lang/Emails/mastersigned.es.yml +41 -0
  254. milpa_core-0.3.1/src/milpa/Resources/Lang/Emails/test.en.yml +13 -0
  255. milpa_core-0.3.1/src/milpa/Resources/Lang/Emails/test.es.yml +13 -0
  256. milpa_core-0.3.1/src/milpa/Resources/Static/welcome.css +19 -0
  257. milpa_core-0.3.1/src/milpa/Resources/Views/Emails/Trans/Footer/email_footer.html.j2 +31 -0
  258. milpa_core-0.3.1/src/milpa/Resources/Views/Emails/Trans/Styles/basic.html.j2 +133 -0
  259. milpa_core-0.3.1/src/milpa/Resources/Views/Emails/Trans/master.html.j2 +40 -0
  260. milpa_core-0.3.1/src/milpa/Resources/Views/Emails/Trans/mastersigned.html.j2 +35 -0
  261. milpa_core-0.3.1/src/milpa/Resources/Views/Emails/Trans/test.html.j2 +21 -0
  262. milpa_core-0.3.1/src/milpa/Resources/Views/Emails/Trans/testsigned.html.j2 +22 -0
  263. milpa_core-0.3.1/src/milpa/Resources/Views/index.html.j2 +16 -0
  264. milpa_core-0.3.1/src/milpa/__init__.py +8 -0
  265. milpa_core-0.3.1/src/milpa/_skeleton/.env.example.tmpl +47 -0
  266. milpa_core-0.3.1/src/milpa/_skeleton/.gitignore.tmpl +20 -0
  267. milpa_core-0.3.1/src/milpa/_skeleton/README.md.tmpl +40 -0
  268. milpa_core-0.3.1/src/milpa/_skeleton/app/Console/Commands/__init__.py.tmpl +0 -0
  269. milpa_core-0.3.1/src/milpa/_skeleton/app/Console/__init__.py.tmpl +0 -0
  270. milpa_core-0.3.1/src/milpa/_skeleton/app/Models/User.py.tmpl +22 -0
  271. milpa_core-0.3.1/src/milpa/_skeleton/app/Models/__init__.py.tmpl +15 -0
  272. milpa_core-0.3.1/src/milpa/_skeleton/app/Modules/Hello/Http/HelloController.py.tmpl +27 -0
  273. milpa_core-0.3.1/src/milpa/_skeleton/app/Modules/Hello/Http/__init__.py.tmpl +0 -0
  274. milpa_core-0.3.1/src/milpa/_skeleton/app/Modules/Hello/__init__.py.tmpl +0 -0
  275. milpa_core-0.3.1/src/milpa/_skeleton/app/Modules/__init__.py.tmpl +0 -0
  276. milpa_core-0.3.1/src/milpa/_skeleton/app/Resources/Views/welcome.html.j2.tmpl +27 -0
  277. milpa_core-0.3.1/src/milpa/_skeleton/app/__init__.py.tmpl +0 -0
  278. milpa_core-0.3.1/src/milpa/_skeleton/docker-compose.yml.tmpl +25 -0
  279. milpa_core-0.3.1/src/milpa/_skeleton/jornal.tmpl +17 -0
  280. milpa_core-0.3.1/src/milpa/_skeleton/logs/.gitkeep.tmpl +1 -0
  281. milpa_core-0.3.1/src/milpa/_skeleton/migrations/env.py.tmpl +50 -0
  282. milpa_core-0.3.1/src/milpa/_skeleton/migrations/script.py.mako.tmpl +27 -0
  283. milpa_core-0.3.1/src/milpa/_skeleton/migrations/versions/.gitkeep.tmpl +1 -0
  284. milpa_core-0.3.1/src/milpa/_skeleton/pyproject.toml.tmpl +25 -0
  285. milpa_core-0.3.1/uv.lock +1714 -0
@@ -0,0 +1,17 @@
1
+ # Entorno y caches locales (la imagen instala sus propias dependencias).
2
+ .venv/
3
+ __pycache__/
4
+ *.pyc
5
+ *.pyo
6
+
7
+ # Secretos y datos que NUNCA deben entrar a la imagen (se montan como volumen).
8
+ .env
9
+ secrets/
10
+ logs/
11
+
12
+ # Cosas del editor / control de versiones.
13
+ .idea/
14
+ .git/
15
+ .gitignore
16
+ .claude
17
+ README.md
@@ -0,0 +1,118 @@
1
+ # Copia este archivo a .env y ajusta. Estos valores asumen ejecución en DOCKER.
2
+ # Si corres en el HOST (uv run), usa localhost/127.0.0.1 en las URLs.
3
+
4
+ # --- Infraestructura ---
5
+ DATABASE_URL=mysql+pymysql://<user>:<password>@<host>:<port>/<database>
6
+
7
+ # --- Colas / broker-agnostic (ver docs/research/broker_agnostic_plan.md) ---
8
+ # BROKER_URL: vacío => redis local por default. Solo se usa para lo ENCOLADO (los
9
+ # flujos síncronos no lo tocan). Cambia el transporte sin tocar código:
10
+ # Redis: redis://localhost:6379/0
11
+ # RabbitMQ: amqp://guest:guest@localhost:5672// (docker compose ya lo levanta)
12
+ BROKER_URL=
13
+ # Result backend: OPCIONAL (crons fire-and-forget). Vacío => sin backend.
14
+ RESULT_BACKEND_URL=
15
+ # Store de locks para without_overlapping (redis). Vacío => redis local por default.
16
+ LOCK_URL=
17
+ # Reintentos de tasks ante fallos TRANSITORIOS (backoff exponencial con jitter). Son los
18
+ # DEFAULTS de retry_policy(); se pueden pisar A MANO en código por-task. Solo afectan a
19
+ # tasks que OPTAN por reintentar (autoretry_for), NUNCA a crons. 0 => sin reintentos.
20
+ TASK_MAX_RETRIES=3
21
+ TASK_RETRY_BACKOFF=2 # segundos base del 1er reintento (luego se duplica)
22
+ TASK_RETRY_BACKOFF_MAX=600 # tope del backoff entre reintentos (10 min)
23
+ #
24
+ # CLOUD (EDUCATIVO / EN CONSTRUCCIÓN — basado en docs, NO probado en docker, sin
25
+ # mantenimiento garantizado estos primeros meses; solo de referencia):
26
+ # AWS SQS: BROKER_URL=sqs://<AWS_KEY>:<AWS_SECRET>@ (dep: celery[sqs])
27
+ # Azure SB: BROKER_URL=azureservicebus://<SAS>@<namespace> (dep: azure-servicebus)
28
+ # GCP Pub/Sub: BROKER_URL=gcpubsub://projects/<PROJECT_ID> (dep: celery[gcpubsub])
29
+ # ActiveMQ NO es compatible con Celery (AMQP 1.0). Usa RabbitMQ como MQ.
30
+ # Si se omite, el default es la zona del HOST. IMPORTANTE fijarla explícita: un
31
+ # server suele estar en UTC y quien lo monta puede no ser quien programa.
32
+ TIMEZONE=America/Mexico_City
33
+ APP_ENV=local
34
+ # Nombre del proyecto (el default del framework es genérico "App"; pon el tuyo).
35
+ APP_NAME="My App"
36
+ # Locale de fallback de i18n (correos, API, etc.) cuando no se pasa uno explícito.
37
+ APP_FALLBACK_LOCALE=es
38
+ # Locale de Faker para factories/seeders (datos falsos). Cualquier locale de Faker:
39
+ # es_MX, es_ES, en_US, pt_BR, ... Default: es_MX.
40
+ FAKER_LOCALE=es_MX
41
+ # NUNCA en true contra la BD legacy (no debe crear/alterar tablas).
42
+ AUTO_CREATE_TABLES=false
43
+ # Puerto del servidor FastAPI (uvicorn --port).
44
+ APP_PORT=8000
45
+
46
+ # --- HTTP / middlewares (coma-separados; defaults SEGUROS si se omiten) ---
47
+ # CORS: vacío => NO se monta (same-origin). En dev pon el origin de tu front:
48
+ CORS_ALLOW_ORIGINS= # ej: http://localhost:3000,https://app.tudominio.com
49
+ CORS_ALLOW_METHODS=* # en prod restringe: GET,POST,PUT,DELETE
50
+ CORS_ALLOW_HEADERS=*
51
+ CORS_ALLOW_CREDENTIALS=false # true requiere orígenes explícitos (no "*")
52
+ # TrustedHost: "*" = off. En prod fija dominios (anti Host-header attack):
53
+ TRUSTED_HOSTS=* # ej: api.tudominio.com,*.tudominio.com
54
+ # GZip: off por default (mejor en nginx/proxy en prod).
55
+ GZIP_ENABLED=false
56
+ # Security headers (defensivos). El trío seguro (nosniff/X-Frame-Options/Referrer-Policy)
57
+ # va ON por default; todo es apagable. HSTS OFF por default: enciéndelo SOLO sirviendo
58
+ # HTTPS (en prod, tras TLS). CSP vacío = no se manda (es específico de cada app).
59
+ SECURITY_HEADERS_ENABLED=true
60
+ SECURITY_FRAME_OPTIONS=DENY # DENY | SAMEORIGIN | "" (no mandar)
61
+ SECURITY_REFERRER_POLICY=no-referrer
62
+ HSTS_ENABLED=false # true SOLO con HTTPS (en prod)
63
+ HSTS_MAX_AGE=31536000
64
+ HSTS_INCLUDE_SUBDOMAINS=true
65
+ CONTENT_SECURITY_POLICY= # ej: default-src 'self'
66
+ # Errores en formato RFC 9457 (application/problem+json). Base del campo `type`: vacío =>
67
+ # "about:blank". Si publicas docs de errores, apúntalo: https://tudominio.com/problems
68
+ PROBLEM_BASE_URL=
69
+
70
+ # --- Auth propia (login de milpa: JWT API + sesión cookie) ---
71
+ AUTH_GUARD=jwt # guard por default: jwt | session | passport
72
+ AUTH_USER_MODEL=milpa.Models.User.User
73
+ JWT_SECRET= # OBLIGATORIO para emitir/validar JWT propios (genera uno largo y aleatorio)
74
+ JWT_ALGORITHM=HS256
75
+ JWT_TTL_SECONDS=3600
76
+ # Prefijo de TODAS las cookies. Si SESSION_COOKIE/CSRF_COOKIE quedan vacíos, se derivan como
77
+ # <COOKIE_PREFIX>_session / <COOKIE_PREFIX>_csrf. Default: milpa.
78
+ COOKIE_PREFIX=milpa
79
+ # Sesión cookie (carril browser/HTMX). SESSION_SECRET vacío => no se monta la sesión.
80
+ # HttpOnly siempre; SESSION_SECURE=true en prod (HTTPS).
81
+ SESSION_SECRET= # genera uno largo y aleatorio para usar el guard 'session'
82
+ # SESSION_COOKIE= # vacío => <COOKIE_PREFIX>_session
83
+ SESSION_TTL_SECONDS=1209600 # 14 días
84
+ SESSION_SECURE=false # true en PROD (HTTPS)
85
+ SESSION_SAME_SITE=lax # lax | strict | none
86
+ # CSRF (double-submit): protege el carril cookie/sesión; exime bearer/JWT.
87
+ CSRF_ENABLED=true
88
+ # CSRF_COOKIE= # vacío => <COOKIE_PREFIX>_csrf
89
+ CSRF_HEADER=X-CSRF-Token
90
+
91
+ # --- Auth: validar tokens OAuth2 de Laravel Passport (tokens EXTERNOS, migración) ---
92
+ # Copia la llave pública del legacy (storage/oauth-public.key) a ./secrets/
93
+ # y apunta aquí a su ruta.
94
+ PASSPORT_PUBLIC_KEY_PATH=/secrets/oauth-public.key
95
+ # PASSPORT_EXPECTED_AUDIENCE=
96
+
97
+ # --- Logging (Loguru) ---
98
+ LOG_LEVEL=INFO
99
+ # LOG_JSON=true agrega logs/app.jsonl (JSON Lines) para Loki/Grafana.
100
+ LOG_JSON=false
101
+
102
+ # --- Correo ---
103
+ # MAIL_DRIVER: cómo se manda. smtp = SMTP real | log = lo escribe en el log (dev sin
104
+ # SMTP, cross-platform) | null = no-op (lo descarta).
105
+ MAIL_DRIVER=smtp
106
+ # En local apunta a Mailpit (puertos del docker-compose).
107
+ MAILPIT_SMTP_PORT=1025
108
+ MAILPIT_UI_PORT=8025
109
+ MAIL_HOST=<host> # ej. localhost (host) o mailpit (docker)
110
+ MAIL_PORT=1025
111
+ MAIL_USERNAME=
112
+ MAIL_PASSWORD=
113
+ MAIL_ENCRYPTION= # "" sin cifrado (Mailpit) | tls (STARTTLS) | ssl (SMTPS)
114
+ MAIL_FROM_ADDRESS=no-reply@example.com
115
+ MAIL_FROM_NAME="My App"
116
+ # Destinatarios de sistema (fallback si system_config no trae el name; CCO por APP_ENV si vacío).
117
+ ADMIN_SYSTEM_MAILS=
118
+ MAIL_CCO_RECIPIENT=
@@ -0,0 +1,65 @@
1
+ name: CI
2
+
3
+ # Corre los MISMOS guardrails que en local (README §7) en cada push a main y en cada PR.
4
+ # Sin `docker build`: por diseño la app NO va en Docker (README §5; Docker solo infra).
5
+ on:
6
+ push:
7
+ branches: [main]
8
+ pull_request:
9
+
10
+ # Cancela corridas viejas del mismo ref si llega un push nuevo.
11
+ concurrency:
12
+ group: ci-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ jobs:
16
+ quality:
17
+ name: Lint + Types + Imports + Tests
18
+ runs-on: ubuntu-latest
19
+ # Sin .env en CI: damos un sqlite dummy explícito (DATABASE_URL ya tiene default, pero
20
+ # lo dejamos claro). Basta para importar (el engine es perezoso) y los tests son sin BD.
21
+ env:
22
+ DATABASE_URL: "sqlite://"
23
+ steps:
24
+ - name: Checkout
25
+ uses: actions/checkout@v5
26
+
27
+ - name: Instalar uv (con Python 3.14 + caché)
28
+ uses: astral-sh/setup-uv@v8.1.0
29
+ with:
30
+ python-version: "3.14"
31
+ enable-cache: true
32
+
33
+ - name: Sincronizar dependencias (incluye grupo dev; reproducible con el lock)
34
+ run: uv sync --frozen
35
+
36
+ # Los 5 guardrails, en pasos separados para ver de un vistazo cuál falla.
37
+ - name: Ruff format (solo verifica)
38
+ run: uv run ruff format --check .
39
+
40
+ - name: Ruff lint
41
+ run: uv run ruff check .
42
+
43
+ - name: Mypy (estricto)
44
+ run: uv run mypy
45
+
46
+ - name: Fronteras entre módulos (import-linter)
47
+ run: uv run lint-imports
48
+
49
+ - name: Pytest (rápidos, sin BD)
50
+ run: uv run pytest
51
+
52
+ # --- Gates de empaquetado (Fase D): el wheel se construye e instala/usa en limpio ---
53
+ - name: Build sanity (uv build construye sdist + wheel)
54
+ run: uv build
55
+
56
+ - name: Smoke de instalación (wheel limpio + scaffolder milpa new)
57
+ run: |
58
+ uv venv /tmp/milpa-smoke
59
+ uv pip install --python /tmp/milpa-smoke/bin/python dist/*.whl
60
+ /tmp/milpa-smoke/bin/python -c "import milpa; print('milpa', milpa.__version__)"
61
+ ( cd /tmp && /tmp/milpa-smoke/bin/milpa new smokeapp )
62
+ test -f /tmp/smokeapp/app/Modules/Hello/Http/HelloController.py
63
+ # El controller generado debe IMPORTAR (ejecuta @Controller/@Get): cubre que el
64
+ # skeleton no esté roto, no solo que el archivo exista.
65
+ ( cd /tmp/smokeapp && /tmp/milpa-smoke/bin/python -c "import app.Modules.Hello.Http.HelloController; print('scaffolder OK')" )
@@ -0,0 +1,54 @@
1
+ name: Release (PyPI)
2
+
3
+ # Publica a PyPI cuando empujas un tag de versión (p. ej. `git tag v0.3.0a0 && git push --tags`).
4
+ # Usa Trusted Publishing (OIDC): NO hay tokens ni secretos — PyPI confía en este workflow.
5
+ # Requisito una sola vez: configurar el "pending publisher" en PyPI (ver docs/prerelease/07).
6
+ on:
7
+ push:
8
+ tags: ["v*"]
9
+
10
+ jobs:
11
+ release:
12
+ name: Build + Publish (Trusted Publishing OIDC)
13
+ runs-on: ubuntu-latest
14
+ # 'environment' protege el publish: puedes exigir aprobación manual en Settings → Environments.
15
+ environment: pypi
16
+ permissions:
17
+ id-token: write # OBLIGATORIO para OIDC (Trusted Publishing, sin tokens)
18
+ contents: read # con un bloque permissions explícito, GitHub recorta el resto a 'none'
19
+ env:
20
+ DATABASE_URL: "sqlite://"
21
+ steps:
22
+ - name: Checkout
23
+ uses: actions/checkout@v5
24
+
25
+ - name: Instalar uv (Python 3.14 + caché)
26
+ uses: astral-sh/setup-uv@v8.1.0
27
+ with:
28
+ python-version: "3.14"
29
+ enable-cache: true
30
+
31
+ - name: Sincronizar dependencias (reproducible con el lock)
32
+ run: uv sync --frozen
33
+
34
+ # --- Los 5 guardrails ANTES de publicar: no se publica algo roto ---
35
+ - name: Ruff format
36
+ run: uv run ruff format --check .
37
+ - name: Ruff lint
38
+ run: uv run ruff check .
39
+ - name: Mypy
40
+ run: uv run mypy
41
+ - name: Import-linter
42
+ run: uv run lint-imports
43
+ - name: Pytest
44
+ run: uv run pytest
45
+
46
+ - name: Construir sdist + wheel
47
+ run: uv build --no-sources
48
+
49
+ # uv detecta el OIDC de GitHub Actions y publica vía Trusted Publishing (sin tokens).
50
+ # (el default es --trusted-publishing automatic; no se pasa flag).
51
+ # Tip primer release: si falla el OIDC, cambia temporalmente a
52
+ # `uv publish --trusted-publishing always` para ver el error exacto.
53
+ - name: Publicar a PyPI
54
+ run: uv publish
@@ -0,0 +1,45 @@
1
+ # Entorno Python
2
+ .venv/
3
+ __pycache__/
4
+ *.pyc
5
+ *.pyo
6
+
7
+ # Caches de herramientas (se regeneran solas; NO se versionan). graphify también las
8
+ # IGNORA al indexar porque respeta .gitignore — antes ensuciaban el grafo con nodos basura.
9
+ .import_linter_cache/
10
+ .ruff_cache/
11
+ .pytest_cache/
12
+ .mypy_cache/
13
+ .claude/settings.local.json
14
+
15
+ # Secretos y configuración local (NUNCA al repo)
16
+ .env
17
+ # Ignora TODO el contenido de secrets/ (llaves, etc.) pero conserva la carpeta vacía.
18
+ secrets/*
19
+ !secrets/.gitkeep
20
+
21
+ # Logs (no versionamos contenido, sí la carpeta)
22
+ logs/*
23
+ !logs/.gitkeep
24
+
25
+ # BD sqlite local (p. ej. la del demo: DATABASE_URL=sqlite:///milpa.db)
26
+ *.db
27
+ *.sqlite3
28
+
29
+ # Runtime: PID del servidor web (lo escribe start.sh, lo lee stop.sh)
30
+ app.pid
31
+
32
+ # Handoff local entre sesiones (estado actual + pendientes); NO se versiona.
33
+ NEXT_SESSION.md
34
+
35
+ # Editor / SO
36
+ .idea/
37
+ .DS_Store
38
+ docs/
39
+
40
+ # Sitio generado por MkDocs (se construye en CI; no se versiona)
41
+ site/
42
+
43
+ # Artefactos de build/empaquetado (uv build)
44
+ /dist/
45
+ *.egg-info/
@@ -0,0 +1,146 @@
1
+ # Changelog
2
+
3
+ Todos los cambios notables de **milpa** se documentan aquí.
4
+
5
+ El formato sigue [Keep a Changelog](https://keepachangelog.com/es-ES/1.1.0/) y el proyecto usa
6
+ [Versionado Semántico](https://semver.org/lang/es/). En `0.x` la API puede cambiar entre minors.
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.3.1] - 2026-06-02
11
+
12
+ Primer release **publicado a PyPI**. Consolida el paquete instalable (extraído en `0.3.0a0`) con el
13
+ set completo de patrones estilo milpa, la API REST estilo DRF, el demo integral y el manual.
14
+
15
+ ### Added
16
+
17
+ - **Patrones estilo milpa** (OPT-IN, auto-descubribles): `Events`/`Observers` (1:N, transporte
18
+ adaptativo worker/síncrono), `Mediator` (command bus 1:1, transport-neutral HTTP+CLI) y `Pipeline`
19
+ (modelo cebolla). No impuestos: patrones que un arquitecto puede sugerir.
20
+ - **Background**: `@job` (on-demand, `.dispatch()`) separado a propósito de `@cron_task` (agendado).
21
+ - **API REST (estilo DRF)**: versionado (`@Controller(version="v1")`), rate limiting (`@rate_limit`),
22
+ filtering DSL (`FilterQueryModel`) + paginación por cursor, negociación de contenido (una ruta
23
+ sirve JSON o HTML según `Accept`) y serializers Pydantic v2 (`computed_field`).
24
+ - **Módulo `Demo`** integral (reemplaza a `Example`): users/notes ejercitando auth dual, RBAC+ABAC,
25
+ los tres patrones, correos por evento + mailables firmados, y UI HTMX + Alpine + Pico.css.
26
+ - **Manual** ampliado (mkdocs): eventos/observers, mediator, pipeline, jobs, versionado, rate
27
+ limiting, filtrado/paginación, negociación de contenido, serializadores y errores RFC 9457.
28
+ - **Skeleton del scaffolder**: `.env.example` con sección de correo (`MAIL_DRIVER=log` por default,
29
+ que imprime en la terminal de `jornal serve`; Mailpit para inbox web) y `docker-compose.yml`
30
+ (redis + mailpit) para la infra de dev.
31
+
32
+ ### Fixed
33
+
34
+ - **`milpa new --demo` funciona out-of-the-box**: `faker` se incluye en el grupo dev del proyecto
35
+ generado y `Core/Database/Faker.py` da un error accionable si falta (las factories/seeders lo
36
+ necesitan; es dependencia de dev, no de producción).
37
+
38
+ ### Changed
39
+
40
+ - Heredado de `0.3.0a0`: `DATABASE_URL` con default `sqlite`, `pymysql` movido al extra
41
+ `milpa-core[mysql]` (core agnóstico de dialecto), y el paquete importable `app` → `milpa`.
42
+
43
+ ## [0.3.0a0] - 2026-06-01
44
+
45
+ Primera versión **INSTALABLE**: milpa se extrae como paquete (`pip install milpa-core`) con un
46
+ scaffolder de proyectos. Alpha — la API puede cambiar entre versiones.
47
+
48
+ ### Added
49
+
50
+ - **Paquete instalable** (`pip install milpa-core` / `uv add milpa-core`): src-layout (`src/milpa`),
51
+ `[build-system]` hatchling, comando de consola `milpa`, versión single-source en `__init__`.
52
+ - **`milpa new <app>`** — scaffolder que genera un proyecto listo para correr (estilo
53
+ `laravel new` / `django-admin startproject`) desde un skeleton embebido en el paquete.
54
+ - **Config-seam**: el Core resuelve módulos/modelos/recursos/migraciones del proyecto desde
55
+ `Settings`/`.env` (`MODULES_PACKAGE`, `MODELS_PACKAGE`, `USER_VIEWS_DIR`, …) en vez de rutas
56
+ hardcodeadas — un proyecto externo apunta milpa a su propio código. Nuevo `milpa.Core.Discovery`.
57
+ - Pipeline de release a PyPI (Trusted Publishing OIDC) + gates de empaquetado en CI
58
+ (`uv build` + smoke de instalación).
59
+
60
+ ### Changed
61
+
62
+ - **`DATABASE_URL`** ahora tiene default `sqlite:///./milpa.db` (zero-config: milpa arranca sin
63
+ configurar nada, como Django en dev). En QA/prod se pone el motor real en `.env`.
64
+ - **`pymysql`** sale del core → extra opcional `milpa-core[mysql]` (el core queda agnóstico de dialecto).
65
+ - El paquete importable se renombró `app` → `milpa`.
66
+
67
+ ## [0.2.0] - 2026-05-30
68
+
69
+ DX de la consola: más comandos `jornal` (estilo `artisan`) y una lista coherente y legible.
70
+
71
+ ### Added
72
+
73
+ - **`jornal route list`** — lista las rutas HTTP montadas (método/path/nombre) en tabla rich,
74
+ construyendo la app real (≈ `php artisan route:list`).
75
+ - **`jornal db fresh`** — recrea la BD: baja todo, re-migra y siembra. Destructivo; pide
76
+ confirmación salvo `--force` (≈ `php artisan migrate:fresh --seed`).
77
+ - **`jornal make controller|model|module`** — scaffolding idempotente de stubs idiomáticos
78
+ (los controllers se auto-montan por el Registry; nunca sobrescribe un archivo existente)
79
+ (≈ `php artisan make:*`).
80
+
81
+ ### Changed
82
+
83
+ - **`jornal list`** ahora incluye también los comandos raíz (p. ej. `serve`, `list`), no solo los
84
+ agrupados; y estrena título: **🌽 Labores de la milpa**.
85
+ - Descripciones (`help`) de **todos** los comandos normalizadas a un estilo coherente
86
+ `<imperativo>. (≈ php artisan X)`.
87
+
88
+ ### Docs
89
+
90
+ - Guía de BD: cuándo sembrar un **catálogo fijo** en la propia migración con `op.bulk_insert`
91
+ (vs. seeder + factory para datos de ejemplo).
92
+
93
+ ### Tests
94
+
95
+ - Cobertura (sin BD) de los comandos nuevos (registro de `route`/`db`/`make`, delegación de
96
+ `db fresh`, pureza de los stubs) y del `PassportGuard` (sin bearer → `None`, token válido →
97
+ user, token inválido → 401).
98
+
99
+ ## [0.1.0] - 2026-05-30
100
+
101
+ Primera versión: el esqueleto del microframework + auth, demo y herramientas de datos.
102
+
103
+ ### Added
104
+
105
+ #### Kernel / HTTP
106
+ - App factory FastAPI (`create_app`) con auto-discovery de routers por módulo.
107
+ - Routing **class-based** estilo Spring: `@Controller` + `@Get/@Post/@Put/@Patch/@Delete`
108
+ (convive con el estilo `APIRouter`).
109
+ - Errores en **RFC 9457** (`application/problem+json`): `DomainError` y subclases + handler global
110
+ (dominio, validación 422, `HTTPException`, catch-all 500).
111
+ - Middlewares: CORS / TrustedHost / GZip + **SecurityHeaders** (nosniff/X-Frame-Options/HSTS/CSP).
112
+
113
+ #### Auth (modelo Sanctum) + autorización
114
+ - **JWT** propio (HS256), guard `jwt`, `Auth.attempt`; **sesión cookie** firmada + **CSRF**
115
+ double-submit, guard `session`; **PassportGuard** (RS256 externo) para migrar Laravel.
116
+ - `Hash` (argon2id + verifica bcrypt `$2y$` de Laravel), `UserProvider` (SQLAlchemy, overridable),
117
+ `current_user`/`CurrentUser`, `guarded(name)`.
118
+ - **RBAC** (`@Roles`/`require_roles`) + **ABAC** (`Gate.define/authorize`, `@Can`).
119
+ - Nombres de cookie configurables con prefijo (`COOKIE_PREFIX`, default `milpa`).
120
+
121
+ #### Datos (estilo Spring/Laravel)
122
+ - `Repository[Model, Id]` tipado: `get/all/add/delete/find_or_fail/first_or_create` + `paginate()`
123
+ (offset/limit sin COUNT, `Page`). Sesión ambiente (`@transactional`/`session_scope`), soft-delete,
124
+ timestamps. Engine **agnóstico del motor**.
125
+ - **Migraciones** con Alembic (`jornal migrate make/run/status/rollback`).
126
+ - **Seeders** (`jornal db seed`) y **Factories** `Factory[Model]` con **Faker** (locale configurable
127
+ vía `FAKER_LOCALE`).
128
+
129
+ #### Tareas / consola / correo / i18n
130
+ - Celery (broker-agnóstico) + crons `@cron_task` con **retry/backoff** (`retry_policy`).
131
+ - Consola `jornal` (Typer) con auto-discovery y salida en tabla **rich**.
132
+ - Mail (`Mailable`/`Mailer`, drivers smtp/log/null, Jinja2, i18n) y Logging (loguru, JSON).
133
+
134
+ #### Demo + tooling
135
+ - Módulo **Demo** corrible (SQLite): dashboard con auth dual, RBAC+ABAC, **búsqueda en vivo** +
136
+ **scroll infinito** (HTMX), branding StackCraft (Pico.css + Alpine). 100 usuarios vía factories.
137
+ - **CI** (GitHub Actions): ruff + mypy strict + import-linter + pytest. Sitio de docs (MkDocs
138
+ Material) publicable a GitHub Pages.
139
+
140
+ ### Notas
141
+ - Todo es **síncrono** (SQLAlchemy + Celery). Tests **sin base de datos** (fakes + monkeypatch).
142
+
143
+ [Unreleased]: https://github.com/calcifux/milpa/compare/v0.3.1...HEAD
144
+ [0.3.1]: https://github.com/calcifux/milpa/compare/v0.2.0...v0.3.1
145
+ [0.2.0]: https://github.com/calcifux/milpa/compare/v0.1.0...v0.2.0
146
+ [0.1.0]: https://github.com/calcifux/milpa/releases/tag/v0.1.0
@@ -0,0 +1,58 @@
1
+ # Código de Conducta
2
+
3
+ ## Nuestro compromiso
4
+
5
+ Como miembros, contribuyentes y mantenedores, nos comprometemos a hacer de la
6
+ participación en **milpa** una experiencia libre de acoso,
7
+ acogedora y respetuosa para todas las personas, sin importar su origen o
8
+ identidad. Nos comprometemos a actuar e interactuar de formas que construyan una
9
+ comunidad abierta, amable, diversa y sana.
10
+
11
+ ## Nuestros estándares
12
+
13
+ Ejemplos de comportamiento que ayudan a crear un ambiente positivo:
14
+
15
+ - Mostrar empatía y amabilidad hacia los demás
16
+ - Respetar opiniones, puntos de vista y experiencias distintas
17
+ - Dar y aceptar con gracia retroalimentación constructiva
18
+ - Asumir la responsabilidad, disculparse con quienes se vean afectados por
19
+ nuestros errores y aprender de ellos
20
+ - Enfocarse en lo que es mejor para la comunidad en su conjunto
21
+
22
+ El acoso, las conductas abusivas o irrespetuosas, los ataques personales o
23
+ políticos, publicar información privada de terceros sin su consentimiento y
24
+ cualquier otra conducta que una persona razonable consideraría inapropiada en un
25
+ entorno profesional **no se toleran**.
26
+
27
+ ## Estándar adoptado
28
+
29
+ Este proyecto adopta el **[Contributor Covenant, versión 2.1](https://www.contributor-covenant.org/es/version/2/1/code_of_conduct/)**.
30
+ El texto completo —con los estándares detallados y las cuatro guías de aplicación
31
+ (Corrección → Advertencia → Expulsión temporal → Expulsión permanente)— aplica a
32
+ este proyecto. Por favor léelo ahí.
33
+
34
+ ## Alcance
35
+
36
+ Este Código de Conducta aplica en todos los espacios del proyecto (issues, pull
37
+ requests, discusiones, código) y cuando una persona representa oficialmente al
38
+ proyecto en espacios públicos.
39
+
40
+ ## Aplicación
41
+
42
+ Las personas mantenedoras son responsables de aclarar y hacer cumplir estos
43
+ estándares, y pueden eliminar, editar o rechazar contribuciones que no se
44
+ alineen con este Código de Conducta.
45
+
46
+ Las instancias de comportamiento abusivo, de acoso o de cualquier otra forma
47
+ inaceptable pueden reportarse **en privado** a la persona mantenedora
48
+ (`@calcifux`) vía GitHub (abrir un *private security advisory* o contactarla
49
+ directamente).
50
+ <!-- TODO: agrega un email de contacto dedicado si prefieres uno en vez de GitHub. -->
51
+ Todas las quejas serán revisadas e investigadas de forma rápida y justa. Las
52
+ personas mantenedoras están obligadas a respetar la privacidad y la seguridad de
53
+ quien reporta.
54
+
55
+ ## Atribución
56
+
57
+ Este Código de Conducta es una adaptación del
58
+ [Contributor Covenant](https://www.contributor-covenant.org/es/), versión 2.1.
@@ -0,0 +1,148 @@
1
+ # Contribuir a milpa
2
+
3
+ ¡Gracias por tu interés en contribuir! Este documento explica cómo levantar el proyecto
4
+ en local, las convenciones que seguimos y cómo enviar un Pull Request con las mejores
5
+ probabilidades de merge.
6
+
7
+ > Si vas a tocar un subsistema, lee primero su página en
8
+ > [`documentation/`](documentation/README.md): ahí está el "cómo funciona".
9
+
10
+ ## Inicio rápido
11
+
12
+ ```bash
13
+ git clone https://github.com/calcifux/milpa.git
14
+ cd milpa
15
+ uv sync # crea el venv y resuelve deps (incluye las de dev)
16
+ cp .env.example .env # ajusta al menos DATABASE_URL
17
+ uv run pytest # si la suite pasa, ya puedes desarrollar
18
+ ```
19
+
20
+ Si no usas `uv`, ver [documentation/02-instalacion.md](documentation/02-instalacion.md)
21
+ (opción pip). Con `uv`, antepón `uv run` a los comandos; con el venv activo, omítelo.
22
+
23
+ > **¿Quieres ver algo funcionando ya?** Corre el demo (sqlite, sin infra):
24
+ > ```bash
25
+ > uv run python jornal migrate run && uv run python jornal db seed && uv run python jornal serve
26
+ > # http://127.0.0.1:8000 · admin@demo.test / password
27
+ > ```
28
+ > Auth dual (JWT + sesión/CSRF), RBAC + ABAC, búsqueda + scroll infinito, factories con Faker.
29
+
30
+ ## Requisitos
31
+
32
+ - **Python 3.14+**
33
+ - **[uv](https://docs.astral.sh/uv/)** (recomendado) como gestor de entorno y deps
34
+ - **Docker NO** es necesario para los tests: son unitarios y **sin base de datos** (usan
35
+ fakes y monkeypatch, no servicios vivos). Docker solo hace falta para correr la app de
36
+ verdad (Redis + Mailpit), no para contribuir/testear.
37
+ - **Git** con auth SSH o HTTPS a GitHub
38
+
39
+ ## Estructura del repo
40
+
41
+ ```
42
+ app/
43
+ Core/ ← EL FRAMEWORK (kernel genérico, reutilizable)
44
+ Models/ ← modelos SQLAlchemy compartidos (auto-discovery)
45
+ Dictionaries/ ← constantes de dominio compartidas
46
+ Modules/ ← los módulos del proyecto (independientes entre sí)
47
+ Resources/ ← vistas/lang/estáticos compartidos
48
+ Tests/ ← espeja app/ 1:1; tests unitarios sin BD
49
+ documentation/ ← guía estilo Laravel (pública)
50
+ jornal ← entrypoint de consola (el "artisan")
51
+ ```
52
+
53
+ Detalle en [documentation/04-estructura-directorios.md](documentation/04-estructura-directorios.md).
54
+
55
+ ## Las dos fronteras (no las rompas)
56
+
57
+ `import-linter` las fuerza en CI:
58
+
59
+ 1. **El kernel no depende de los módulos**: `app.Core` / `app.Models` / `app.Dictionaries`
60
+ no importan `app.Modules`.
61
+ 2. **Los módulos son independientes entre sí**: `app.Modules.A` no importa `app.Modules.B`.
62
+
63
+ Si dos módulos necesitan compartir algo, ese algo sube al kernel compartido. Ver
64
+ [documentation/06-monolito-modular.md](documentation/06-monolito-modular.md).
65
+
66
+ ## Ramas y commits
67
+
68
+ - `main` siempre verde. No hagas push directo; abre un PR.
69
+ - Ramas de feature: `feat/mail-cc-bcc`, `fix/cron-lock-timeout`, `docs/install-guide`.
70
+ - [Conventional Commits](https://www.conventionalcommits.org/): `feat:`, `fix:`, `docs:`,
71
+ `refactor:`, `test:`, `ci:`, `chore:`.
72
+
73
+ ## Estilo de código
74
+
75
+ - Identificadores en **inglés**; comentarios y docstrings en **español**, explicando el
76
+ *porqué* (no abreviar).
77
+ - Sin emojis en código/comentarios/docstrings.
78
+ - Tipos completos: `mypy` corre en modo **estricto** sobre `app/` y `Tests/Core`.
79
+ - Un archivo por clase/responsabilidad (estilo Laravel/PascalCase en `app/`).
80
+ - Formato e imports los maneja **Ruff** (no formatees a mano).
81
+
82
+ ## Guardrails (lo que valida CI)
83
+
84
+ Antes de abrir el PR, corre todo y déjalo verde:
85
+
86
+ ```bash
87
+ uv run ruff format . # formato | --check solo verifica (modo CI)
88
+ uv run ruff check . # lint | --fix arregla lo auto-arreglable
89
+ uv run mypy # tipos (estricto)
90
+ uv run lint-imports # fronteras entre módulos
91
+ uv run pytest # tests (rápidos, sin BD)
92
+ ```
93
+
94
+ Todo de una:
95
+
96
+ ```bash
97
+ uv run ruff format --check . && uv run ruff check . && uv run mypy && uv run lint-imports && uv run pytest
98
+ ```
99
+
100
+ ## Contribuir al Core
101
+
102
+ milpa es un **framework**: las contribuciones van al **kernel** (`app/Core`), a sus tests
103
+ (`Tests/Core`) y a la documentación. **No** se trata de crear módulos de negocio nuevos —
104
+ eso lo hace cada proyecto que *usa* milpa, en su propio repo. `app/Modules/Example` es
105
+ solo el módulo de **referencia/demo**: tócalo únicamente para demostrar una capacidad del
106
+ Core, no para meter features de dominio.
107
+
108
+ Al tocar el Core:
109
+
110
+ 1. **Mantén el Core genérico.** Nada de dominio ni de un proyecto en particular (ni
111
+ nombres, ni reglas de negocio): el kernel debe servir igual a cualquier proyecto. Si
112
+ dudas si algo es "del framework" o "de un proyecto", probablemente no va en Core.
113
+ 2. **Respeta la frontera `app.Core ↛ app.Modules`**: el kernel no importa módulos (el
114
+ discovery es dinámico, no por imports estáticos). Lo valida `lint-imports`.
115
+ 3. **Espeja la estructura por capas**: cada subsistema vive en `app/Core/<Subsistema>/`
116
+ con un `__init__.py` que expone su API pública.
117
+ 4. **Agrega tests** en `Tests/Core/...` (sin BD) y, si cambia comportamiento público,
118
+ **documéntalo** en `documentation/`.
119
+
120
+ Para entender un subsistema antes de tocarlo, lee su página en
121
+ [documentation/](documentation/README.md).
122
+
123
+ ## Tests
124
+
125
+ - Espeja `app/` en `Tests/` (misma ruta). Tests **unitarios y sin BD**: usa fakes y
126
+ monkeypatch, no levantes Postgres/Redis.
127
+ - Los tests escriben su log en `logs/tests/` (lo fija `Tests/conftest.py`), no en
128
+ `logs/app.log`.
129
+ - Corre uno solo: `uv run pytest Tests/Core/Mail/test_Mailer.py -x`.
130
+
131
+ ## Checklist del PR
132
+
133
+ - [ ] `ruff format --check .` y `ruff check .` pasan
134
+ - [ ] `mypy` pasa (estricto)
135
+ - [ ] `lint-imports` pasa (no rompiste las fronteras)
136
+ - [ ] `pytest` pasa
137
+ - [ ] Subject en Conventional Commits
138
+ - [ ] Sin datos personales, secretos ni credenciales
139
+ - [ ] Si cambió comportamiento público, actualizaste `documentation/`
140
+
141
+ ## Código de Conducta
142
+
143
+ Este proyecto adopta el [Código de Conducta](CODE_OF_CONDUCT.md) (Contributor Covenant
144
+ 2.1). Al participar, aceptas cumplirlo.
145
+
146
+ ## Licencia
147
+
148
+ Al contribuir aceptas que tu aporte queda bajo la [Licencia MIT](LICENSE).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 @Calcifux (Carlos Guillermo Reyes Ramiro)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.