AGENT SKILL

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

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 tem status + 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ção REQUIRE_DOCKER em config/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=false em 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ó com coordenador_acompanha=True; ver ocupa_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 T impede QUALQUER evento no intervalo. Código T.
  • RD-03 — Bloqueio parcial (P): bloqueio P impede 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 M em nenhum caminho (de 02/10 a 05/10 foi aviso; antes barrava). O parâmetro AVAILABILITY_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ó com coordenador_acompanha=True; convidado não conta; a mesma pessoa conta uma vez por evento. SSOT services/horas_formacao.py (ocupacoes_aprovadas: Grade Mensal ch_month/ch_year, painel de Equipe horas_trabalhadas e 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); warnings só 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 Conflict carrega code, title, detail (formador e intervalo HH:MM dd/mm) e ref_id opcional. Os códigos emitidos são X, T, P e D; 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): Solicitacao com projeto.fluxo == 'SUPER' NUNCA vira "aprovado" automaticamente, mesmo sem conflito. Decidido por resolve_initial_status() (apps/core/services/solicitacao_create.py:23), chamado no perform_create do SolicitacaoViewSet (views_solicitacao.py) — não há override de Solicitacao.save().
  • PA-02 — Perfil exigido: regra única solicitation_approval_basis; ver PA-02 em v2/docs/specs/domain/politica-aprovacao.spec.md (nenhum grupo aprova). Idioma canônico permission_classes = [HasPerm("codename")] (from apps.core.rbac import HasPerm; políticas em apps/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 capacidade create_solicitation_without_purchase): aí nasce pendente em qualquer fluxo (resolve_initial_status(sem_compra=True), marca par_sem_compra da Regra 4 do SolicitacaoSerializer; 03/11/2026). Ver o adendo da PA-04 sobre evento sem compra em politica-aprovacao.spec.md. Os importadores não passam sem_compra.
  • PA-05 — Auditoria: registra usuário, data/hora e justificativa em AuditLog (APPROVE/REJECT, com solicitacao_id, prev_status, new_status, justificativa; não existe model Aprovacao). 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.tsx renderiza Approve/Reject só se status === '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. Rodar pytest 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 = command import_export_contract (dry-run por padrão; --apply exige allowlist) + endpoints DRF (POST /api/controle/import-acoes/, /api/dat/import-cadastros/). Idempotência via external_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() retorna AvailabilityResult com lista de ConflictDetail (regras RD-01..RD-08). Endpoints GET /api/availability/check/ e POST /api/availability/check-many/. Frontend pages/Solicitacoes/NewSolicitacaoWizard.tsx com 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) e PATCH .../reject/ (REJECT). Frontend ApprovalsPage.tsx.
  • RF05 — Google Calendar: factory gcal_client_factory.py (fake vs google). Idempotência eventId=asv2{id} (sem hífen: o Google só aceita base32hex) + gcal_payload_hash (SHA1 do payload sem conferenceData; 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_ID e GOOGLE_SERVICE_ACCOUNT_FILE/_JSON só 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, sem conferenceData; is_online=true → online com conferenceData, gera link. Persiste o hangoutLink SÓ no apply real (não em preview/dry_run/409). Componente MeetLink.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). API GET /api/availability/monthly/?year=&month=&role=&sector=&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 Compra antiga 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 (skill etl-guidelines DEPRECADA — 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

matheusnorjosa
matheusnorjosa/aprender_sistema

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.

内容创作者写作与文案
★ 0
matheusnorjosa
matheusnorjosa/aprender_sistema

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.

★ 0
matheusnorjosa
matheusnorjosa/aprender_sistema

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.

测试与质量
★ 0
matheusnorjosa
matheusnorjosa/aprender_sistema

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.

★ 0
matheusnorjosa
matheusnorjosa/aprender_sistema

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.

★ 0
matheusnorjosa
matheusnorjosa/aprender_sistema

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).

人力资源
★ 0