aprender-domain
Business-rules reference for Aprender Sistema v2 — RF (functional requirements), RD (availability rules), PA (approval policy), CP (immutable clauses), and core domain models. Use when implementing a feature, validating a requirement, or writing a compliance test against any RF/RD/PA/CP rule.
- License 许可
- Apache-2.0
- 最近更新
- 2026-11-11
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- aprender-domain
- description
- Business-rules reference for Aprender Sistema v2 — RF (functional requirements), RD (availability rules), PA (approval policy), CP (immutable clauses), and core domain models. Use when implementing a feature, validating a requirement, or writing a compliance test against any RF/RD/PA/CP rule.
02 资源文件 4
- 参考文档reference/compras.md1.6 KB
- 参考文档reference/dat-module.md4.0 KB
- 参考文档reference/key-models.md3.0 KB
- 参考文档reference/plano-formacoes.md3.2 KB
03 SKILL.md 正文
Aprender Sistema v2 — Business Domain
Reference for the stable domain contracts (RF / RD / PA / CP) and core models.
SSOT dos contratos vivos:
v2/docs/specs/domain/*.spec.md(modelo SDD, ADR-017). Cada spec temstatus+last_verified+sources_of_truth. Não duplicar métricas datadas aqui; este skill resume a regra e aponta para a spec viva.
CP (Cláusulas Pétreas) — IMMUTABLE
SSOT: v2/docs/specs/domain/clausulas-petreas.spec.md (CP-01..CP-08).
- CP-01: v2 roda APENAS em Docker (
cd v2 && make up). ValidaçãoREQUIRE_DOCKERemconfig/settings.py. - CP-02: PA-01..PA-07 — aprovação manual obrigatória (ver PA abaixo).
- CP-03: RD-01..RD-08 — disponibilidade com timezone Fortaleza (ver RD abaixo).
- CP-04: Workflow Entender → Planejar → Implementar → Testar. Nunca pular etapas.
- CP-05 a CP-08: v1 congelado; conventional commits; nunca push direto na main (hook);
INCLUDE_DEV_TOOLS=falseem produção.
RD (Regras de Disponibilidade) — Availability Rules
SSOT: v2/docs/specs/domain/regras-disponibilidade.spec.md.
Implementação: apps/core/services/availability_service.py:check_conflicts().
Testes: apps/core/tests/test_availability_service.py.
- RD-01 — Non-overlapping: quem ocupa a agenda (
ENFORCED_ROLES: FORMADOR e, desde 03/11/2026, COORD_ACOMPANHA; o coordenador responsável só comcoordenador_acompanha=True; verocupa_agenda_q) não pode ter dois eventos que se sobreponham (≥1 min).end == starté adjacente, NÃO é conflito. - RD-02 — Bloqueio total (T): bloqueio marcado
Timpede QUALQUER evento no intervalo. CódigoT. - RD-03 — Bloqueio parcial (P): bloqueio
Pimpede eventos só dentro do subintervalo; fora é permitido. - RD-04 — Deslocamento (D): entre municípios diferentes exige tempo mínimo de viagem (configurável). Mesmo município pode ser zero.
- RD-05 — Teto de horas por evento (contagem de CH): desde 05/10/2026 (decisão do dono, OK explícito para mudar RD-05/CP-03) não é checagem de agenda: o motor não emite
Mem nenhum caminho (de 02/10 a 05/10 foi aviso; antes barrava). O parâmetroAVAILABILITY_DAILY_LIMIT_HOURS(Configurações, "Teto de horas por evento (contagem)", 1 a 12, padrão 8) é o teto da contagem de horas de formação: CH de um evento =min(fim − início, teto); as CH do dia somam (sem teto por dia); evento que cruza a meia-noite conta no dia local do início; sem desconto de almoço; online conta; só aprovado, qualquer projeto; conta sempre quem ocupa a agenda pelo papel (ENFORCED_ROLES= FORMADOR e, desde 03/11/2026, COORD_ACOMPANHA, os coordenadores além do responsável); o coordenador responsável (coordenador; sem ele, quem criou) só comcoordenador_acompanha=True; convidado não conta; a mesma pessoa conta uma vez por evento. SSOTservices/horas_formacao.py(ocupacoes_aprovadas: Grade Mensalch_month/ch_year, painel de Equipehoras_trabalhadase a população do ranking de formadores). - RD-06 — Timezone: comparações timezone-aware em
America/Fortaleza; armazenamento em UTC. - RD-07 — Ordem dos checks: (1) blocos T/P → (2) conflitos de eventos aprovados → (3) deslocamento D. Todos barram (
conflicts);warningssó existe na checagem prévia (check/,check-many/) e vem vazio desde 05/10/2026 (saiu do guard e do 400 em 06/10/2026). - RD-08 — Mensagens de conflito: cada
Conflictcarregacode,title,detail(formador e intervaloHH:MM dd/mm) eref_idopcional. Os códigos emitidos sãoX,T,PeD; não há mensagem de limite diário (o RD-05 é contagem de horas, não conflito).
{ "code": "T", "title": "Bloqueio total", "detail": "Maria Silva - 15/01/2025 09:00-12:00", "ref_id": 123 }
PA (Política de Aprovação) — Approval Policy
SSOT: v2/docs/specs/domain/politica-aprovacao.spec.md.
Testes: apps/core/tests/test_approval_policy_PA.py.
- PA-01 — No auto-approval (SUPER):
Solicitacaocomprojeto.fluxo == 'SUPER'NUNCA vira "aprovado" automaticamente, mesmo sem conflito. Decidido porresolve_initial_status()(apps/core/services/solicitacao_create.py:23), chamado noperform_createdoSolicitacaoViewSet(views_solicitacao.py) — não há override deSolicitacao.save(). - PA-02 — Perfil exigido: regra única
solicitation_approval_basis; ver PA-02 emv2/docs/specs/domain/politica-aprovacao.spec.md(nenhum grupo aprova). Idioma canônicopermission_classes = [HasPerm("codename")](from apps.core.rbac import HasPerm; políticas emapps/core/rbac/). - PA-03 — Triggers pós-aprovação: integrações externas (GCal, RF05/RF06) só executam APÓS a aprovação manual; a task de publicação não é chamada na criação (fluxo service-layer:
solicitacao_create.py+views_solicitacao.py). - PA-04 — Estado inicial: SUPER começa em
status = 'pendente'. NAO_SUPER é auto-aprovado na criação (exceção a PA-01), salvo quando o par município+projeto é sem compra e quem cria não é isento (superusuário ou a capacidadecreate_solicitation_without_purchase): aí nascependenteem qualquer fluxo (resolve_initial_status(sem_compra=True), marcapar_sem_comprada Regra 4 doSolicitacaoSerializer; 03/11/2026). Ver o adendo da PA-04 sobre evento sem compra empolitica-aprovacao.spec.md. Os importadores não passamsem_compra. - PA-05 — Auditoria: registra usuário, data/hora e justificativa em
AuditLog(APPROVE/REJECT, comsolicitacao_id,prev_status,new_status,justificativa; não existe modelAprovacao). Actions:APPROVE,REJECT,PREVIEW_GCAL,PUBLISH_GCAL_REQUESTED,PUBLISH_GCAL. - PA-06 — UI/UX: telas de requester/coordenador mostram status e escondem botões sem permissão.
ApprovalsPage.tsxrenderiza Approve/Reject só sestatus === 'pendente' && canApprove. - PA-07 — Testes obrigatórios: os 7 testes nomeados na spec (
v2/docs/specs/domain/politica-aprovacao.spec.md§Testes que cobrem), que é a lista canônica. Rodarpytest apps/core/tests/test_approval_policy_PA.py -v.
RF (Requisitos Funcionais) — Functional Requirements
SSOT: v2/docs/specs/domain/requisitos-funcionais.spec.md.
- RF01 — Import de dados: ETL legado (
apps.dat_ingest) REMOVIDO. Import atual = commandimport_export_contract(dry-run por padrão;--applyexige allowlist) + endpoints DRF (POST /api/controle/import-acoes/,/api/dat/import-cadastros/). Idempotência viaexternal_hash(SHA1/SHA256). Spec:v2/docs/specs/backend/imports.spec.md. - RF02 — Solicitação de evento: página única (
NewSolicitacaoWizard.tsx, desde 28/10/2026). Cada evento é um cartão (CartaoEvento); no cartão, "+ horário" acrescenta um horário, e cada horário vira mais um evento do lote, até 10 (MAX_EVENTOS). O envio é sempre o lote (createSolicitacoesEmLote→POST /api/solicitacoes/lote/, tudo ou nada). O servidor confere conflitos (RF03) e a regra da compra: NAO_SUPER auto-aprova, salvo par sem compra criado por quem não é isento; esse caso e o SUPER ficam pendentes (PA-01..PA-07). - RF03 — Verificação de conflitos:
availability_service.py:check_conflicts()retornaAvailabilityResultcom lista deConflictDetail(regras RD-01..RD-08). EndpointsGET /api/availability/check/ePOST /api/availability/check-many/. Frontendpages/Solicitacoes/NewSolicitacaoWizard.tsxcom feedback visual por tipo: X/T/P/D bloqueiam (alerta vermelho, botão desabilitado); o M (aviso azul) não é mais emitido desde 05/10/2026. - RF04 — Fluxo de aprovação: política PA acima.
PATCH /api/solicitacoes/{id}/approve/(AuditLog APPROVE) ePATCH .../reject/(REJECT). FrontendApprovalsPage.tsx. - RF05 — Google Calendar: factory
gcal_client_factory.py(fake vs google). IdempotênciaeventId=asv2{id}(sem hífen: o Google só aceita base32hex) +gcal_payload_hash(SHA1 do payload semconferenceData; não trocar o algoritmo: invalida os hashes gravados). Retry 3x (1s/2s/4s) para 429/5xx. Preview (/preview-gcal/) gera payload sem persistir; Publish (/publish/) enfileira Celery e retorna 202. Vars:GCAL_CLIENT(fake|google),GCAL_AUTH_MODE(prod =oauth),GCAL_OAUTH_CALENDAR_ID(calendário da organização: publicação e cópia Google→sistema),GCAL_SEND_UPDATES.GCAL_CALENDAR_IDeGOOGLE_SERVICE_ACCOUNT_FILE/_JSONsó valem no modo service account (preagenda_to_gcal, auto-apply). Contrato:v2/docs/specs/backend/gcal.spec.md. - RF06 — Google Meet: campo
meet_link(read-only no serializer).is_online=false(default) → presencial, semconferenceData;is_online=true→ online comconferenceData, gera link. Persiste ohangoutLinkSÓ no apply real (não em preview/dry_run/409). ComponenteMeetLink.tsx. - RF07 — Auditoria: model
AuditLog(usuario, action, model_name, details JSON, created_at). Actions: APPROVE, REJECT, PREVIEW_GCAL, PUBLISH_GCAL_REQUESTED, PUBLISH_GCAL, RESYNC_GCAL_REQUESTED, CANCEL_GCAL_REQUESTED, CANCEL_GCAL. - RF08 — Mapa mensal: página
/disponibilidade, 2 grids (Formadores / Coordenadores), filtros ano/mês/setor/q, linhas virtualizadas, export CSV, cache Redis 5 min. Códigos por célula: E (1 evento), 2 (2+), P/T (bloqueios), X (evento+bloqueio), D/D1 (deslocamento). APIGET /api/availability/monthly/?year=&month=&role=§or=&q=.
Módulos de domínio (REFERENCE)
Fatos consultados sob demanda (modelos, campos, workflows) — abrir só quando precisar:
- DAT (ações, registros, cadastros, coordenadores):
reference/dat-module.md - PlanoFormacoes (planos anuais, formações, acompanhamentos, provas):
reference/plano-formacoes.md - Compras (DATCompra, Produto; a
Compraantiga foi apagada no G29):reference/compras.md - Key Models (Usuario, Municipio, Projeto, Solicitacao, AvailabilityBlock, AuditLog):
reference/key-models.md
Related Skills
django-patterns— padrões de implementação (models, views, serializers).create-plan/implement-plan— arquitetura e planejamento.- Imports/data-loading:
v2/docs/specs/backend/imports.spec.md(skilletl-guidelinesDEPRECADA — ETL legado removido).
Quick Reference Commands
# RD-01..RD-08 (conflitos)
pytest apps/core/tests/test_availability_service.py -v
# PA-01..PA-07 (aprovação)
pytest apps/core/tests/test_approval_policy_PA.py -v
# Google Calendar
pytest apps/core/tests/test_gcal*.py -v
# Import export-contract (dry-run por padrão; --apply exige allowlist)
docker compose exec web python manage.py import_export_contract --path <dir_do_export>
# Imports via API DRF (dry-run)
make import-acoes-dry FILE=...
make import-acoes-dry FILE=...
make import-cadastros-dry FILE=...
04 同仓库更多 Skills
writing-standards
Apply AS v2 technical-writing standards (clarity, brevity, active voice, Python/Django conventions). Use when writing a README, a docstring (PEP 257), a commit message, a PR description, an error message, or any technical doc.
verification-gate
Verify before claiming success. Use when about to say something works/is done, after implementing a feature, after a bugfix, or before pushing — run the proof command and confirm output first.
test-driven-development
Write the failing test before the implementation in AS v2 (pytest + Django/DRF). Use when implementing a feature or fixing a bug, before any production code is written.
subagent-development
Orquestra subagents no AS v2 — decompõe a tarefa em domínios independentes, paraleliza e revisa em 2 estágios. Use ao delegar exploração, implementação ou validação cross-arquivo para acelerar o trabalho e poupar o contexto principal.
security-scan
Automated security scanning for AS v2. Use before commits or when reviewing changes for vulnerabilities. Runs dependency audit (pip-audit, npm audit), secret detection (grep patterns), and code pattern scanning (SQL injection, XSS, eval, pickle, hardcoded secrets). Integrates with project hooks system.
resume-handoff
Resume work from a saved handoff document, validating its state against the current codebase before continuing. Use when resuming work from a saved handoff after a context clear or in a new session (path, session name, or GitHub issue).