{"schema":"testaai.portfolio.v1","schemaUrl":"https://www.testaai.dev.br/en/portfolio.schema.json","language":"en-US","reviewedAt":"2026-08-22","identity":{"brand":"TestaAí","technicalName":"TestaAI","builder":"Zero","role":"Product Engineer / Full-stack Developer","positioning":"Digital products built from problem to operations, with decisions, boundaries, and next signals documented.","disclosure":"Zero is a public persona. Civil identity remains protected while technical data stays open to inspection.","contact":{"status":"pending"}},"capabilities":{"layers":[{"id":"L1","name":"Interface & product","description":"Responsive experiences, complex state, and flows that make the domain visible to operators.","technologies":["React 19","Next.js 16","React Native","Vite","TypeScript"],"evidence":"ERP, Auto Whats, AI_VTT, NEXO, Castle Wars, and Our Home"},{"id":"L2","name":"Services & realtime","description":"APIs, gateways, and isolated processes that protect boundaries and keep interactions synchronized.","technologies":["ASP.NET Core","Fastify","Node.js","Socket.IO","Supabase Realtime"],"evidence":"Renaissance, Auto Whats, Castle Wars, and Our Home"},{"id":"L3","name":"Data & state","description":"Relational persistence, cache, event series, and authoritative rules designed around each use case.","technologies":["PostgreSQL","Redis","ClickHouse","Firebase","Supabase RLS"],"evidence":"seven architectures with different state strategies"},{"id":"L4","name":"Integrations & intelligence","description":"Models, voice, messaging, payments, and external APIs treated as capabilities with explicit limits.","technologies":["AI agents","Baileys","Asaas","ZapSign","ProfitDLL"],"evidence":"automation, generative RPG, fintech, and SaaS operations"}],"principles":[{"id":"BOUNDARIES","name":"Explicit boundaries","description":"Fragile integrations stay at the edges; domain, state, and policy remain testable."},{"id":"SAFE DEFAULTS","name":"Fail safely","description":"Blocked financial execution, human handoff, and authoritative rules are architectural choices."},{"id":"VERTICAL SLICES","name":"Ship end to end","description":"A first usable flow before the complete platform shortens the path from hypothesis to evidence."},{"id":"VISIBLE GAPS","name":"Documented gaps","description":"Anything still in memory, conceptual, or awaiting validation appears without launch language."}]},"projects":[{"id":"renaissance","index":"01","name":"Project Renaissance","seoTitle":"Project Renaissance: quant research and execution","domain":"QUANT / FINTECH","type":"SoftwareApplication","stage":"V1 / SHADOW + PAPER","status":"safe","summary":"A quantitative system built with .NET 10, ProfitDLL, ticks, backtests, strategies, and OMS/Risk. It runs in shadow mode; live execution requires explicit enablement.","question":"Can research, risk, and execution be separated from the first MVP?","scope":"Quantitative research, replay, risk, and controlled execution","role":"Domain architecture, backend, data, and native integration","capabilities":["backend","data","realtime","integrations"],"stack":[".NET 10","ASP.NET Core","PostgreSQL","ClickHouse","ProfitDLL"],"architecture":{"summary":"Research and backtesting → OMS/Risk → isolated x64 adapter → broker, with separate telemetry and persistence.","nodes":[{"code":"INGEST","title":"Market data","detail":"ProfitDLL x64 / normalized ticks"},{"code":"REPLAY","title":"Research engine","detail":"Backtesting and deterministic replay"},{"code":"POLICY","title":"OMS / Risk","detail":"Gates, limits, and order intent"},{"code":"EXEC","title":"Broker adapter","detail":"Shadow, paper, and explicit enablement"}],"centralDecision":"Run ProfitDLL in its own process and keep live execution behind explicit gates; shadow and paper are the defaults.","tradeoffs":[{"axis":"ISOLATION","choice":"Native adapter outside the core","gain":"DLL failures cannot contaminate the domain or primary process.","cost":"More inter-process coordination, health checks, and reconnection."},{"axis":"DATA","choice":"PostgreSQL + ClickHouse","gain":"Operational state and dense series receive appropriate models.","cost":"Two stores require synchronization and deliberate operations."},{"axis":"SAFETY","choice":"Shadow and paper by default","gain":"Research can evolve without silently gaining financial authority.","cost":"Promotion to live execution requires explicit criteria and ceremony."}],"executionTrace":{"trigger":"A normalized tick is received during a paper session.","steps":[{"code":"INGEST","action":"Validates the tick contract, sequence, and clock.","output":"tick.accepted"},{"code":"REPLAY","action":"Runs the active strategy against the same reproducible state.","output":"intent.created | no_op"},{"code":"POLICY","action":"Applies risk, idempotency, and the current mode gates.","output":"intent.allowed | blocked"},{"code":"EXEC","action":"Records the simulation without authorizing a real financial effect.","output":"execution.simulated"}],"invariant":"Without an explicit mode and risk authorization, no adapter produces a real financial effect.","terminalState":"Decision, reason, and correlation remain available for replay and audit."}},"reliability":{"failureModes":["Disconnection or crash in the process that hosts the native DLL.","Missing, duplicated, or out-of-order ticks during ingestion and replay.","An order intent is repeated after a timeout or reconnection."],"candidateSignals":["Identical replays produce the same decision sequence.","Block rate and reason across OMS/Risk gates.","Difference between signal, paper price, and simulated execution result."],"incidentDrills":[{"code":"DRILL-01","scenario":"Disconnection or crash in the process that hosts the native DLL.","containment":"Open the circuit breaker, remove adapter authority, and block new intents before reconnecting.","recovery":"Restart the isolated process, restore the market-data subscription, and reconcile the supervised session cursor.","proof":"Confirm a stable health check, no data gap, and no external order without a corresponding ledger intent."},{"code":"DRILL-02","scenario":"Missing, duplicated, or out-of-order ticks during ingestion and replay.","containment":"Quarantine the inconsistent segment and prevent the strategy from advancing on an untrusted sequence.","recovery":"Request a backfill, normalize order, and replay from the last deterministic checkpoint.","proof":"Compare sequence, checksum, and recovered replay decisions with an intact cut of the same window."},{"code":"DRILL-03","scenario":"An order intent is repeated after a timeout or reconnection.","containment":"Keep the same idempotency key and suspend retry until the adapter state is known.","recovery":"Reconcile intent, acceptance, and execution before completing, canceling, or resending the command.","proof":"Demonstrate one possible financial effect and a complete causal chain for every persisted intent."}]},"nextSignal":"Expand deterministic replays, strategy-promotion criteria, and paper-execution observability.","interviewAngles":["How to design idempotency between an order intent and an external adapter.","Where to separate research, risk policy, and broker infrastructure.","How to promote a strategy without turning a backtest into a promise."],"evidence":{"kind":"documented-architecture"},"links":{"caseStudy":"https://www.testaai.dev.br/en/experiments/renaissance"}},{"id":"erp","index":"02","name":"ERP","seoTitle":"ERP for schools and fitness studios","domain":"OPERATIONS / SAAS","type":"SoftwareApplication","stage":"OPERATIONAL BASE","status":"lab","summary":"Management for schools, fitness studios, and sports operations: students, enrollments, contracts, and billing. It connects signatures, payments, and WhatsApp in one flow.","question":"Can a fragmented operation fit into one coherent workflow?","scope":"Student operations, enrollment, contracts, billing, and communication","role":"Full-stack product, workflow modeling, and SaaS integrations","capabilities":["frontend","backend","data","ai","integrations"],"stack":["React","Vite","Firebase","Asaas","ZapSign"],"architecture":{"summary":"Operational SPA → Firebase services → billing, signature, and WhatsApp adapters.","nodes":[{"code":"OPS","title":"Operations console","detail":"React / role-based journeys"},{"code":"DOMAIN","title":"Business workflow","detail":"Students, enrollment, and contracts"},{"code":"ADAPTERS","title":"External services","detail":"Asaas, ZapSign, and communication"},{"code":"AUDIT","title":"State and reconciliation","detail":"Firebase / operational history"}],"centralDecision":"Model the business flow first and treat payments, signatures, and communication as replaceable integrations.","tradeoffs":[{"axis":"DOMAIN","choice":"Journey before provider","gain":"The product remains legible when an integration changes.","cost":"Adapters and intermediate states require additional modeling."},{"axis":"DELIVERY","choice":"Operational vertical on Firebase","gain":"Authentication, data, and interface reach the real context early.","cost":"Audit and analytical queries need well-defined boundaries."},{"axis":"AUTOMATION","choice":"WhatsApp and AI at the edge","gain":"Communication accelerates without becoming the contract authority.","cost":"Context, consent, and handoff must cross the workflow."}],"executionTrace":{"trigger":"An operator confirms a new enrollment with a contract and billing.","steps":[{"code":"OPS","action":"Validates fields, operator role, and unit context.","output":"enrollment.requested"},{"code":"DOMAIN","action":"Persists the pending enrollment and creates workflow intents.","output":"workflow.committed"},{"code":"ADAPTERS","action":"Dispatches contract and billing with idempotency keys.","output":"provider.references"},{"code":"AUDIT","action":"Reconciles responses and exposes pending work without collapsing states.","output":"operation.visible"}],"invariant":"No isolated provider response alone means the enrollment is complete.","terminalState":"The operator sees state, pending work, external reference, and a recoverable next action."}},"reliability":{"failureModes":["A payment webhook is duplicated or received out of order.","The contract is signed while payment remains unresolved.","An overly broad permission exposes or changes an unauthorized operation."],"candidateSignals":["Time and abandonment between enrollment, signature, and first payment.","Items stuck in the cross-provider reconciliation queue.","Administrative actions recoverable through the audit trail."],"incidentDrills":[{"code":"DRILL-01","scenario":"A payment webhook is duplicated or received out of order.","containment":"Persist the provider receipt and reject any transition that violates the current billing version.","recovery":"Reprocess idempotent events in causal order and query the provider if the sequence remains ambiguous.","proof":"Reconcile value, external reference, and internal state without duplicating settlement, commission, or student communication."},{"code":"DRILL-02","scenario":"The contract is signed while payment remains unresolved.","containment":"Preserve signature and payment as independent states and keep enrollment in an explicit pending state.","recovery":"Resume only the financial step, offering the operator a safe choice to charge, wait, or cancel.","proof":"Show the composed journey, next action, and trail proving that no intermediate state was erased."},{"code":"DRILL-03","scenario":"An overly broad permission exposes or changes an unauthorized operation.","containment":"Revoke the affected session, deny by default, and preserve the record for scope investigation.","recovery":"Correct the role-and-unit policy, recalculate authorization, and require new operator authentication.","proof":"Run the access matrix and confirm in the audit log that reads and mutations follow least privilege."}]},"nextSignal":"Consolidate the audit trail, role-based permissions, and cross-provider failure handling.","interviewAngles":["How to model a saga without hiding intermediate states from the operator.","When to trade managed-backend convenience for custom services.","How to make permissions and audit part of the experience, not a patch."],"evidence":{"kind":"documented-architecture"},"links":{"caseStudy":"https://www.testaai.dev.br/en/experiments/erp"}},{"id":"castle-wars","index":"03","name":"Castle Wars","seoTitle":"Castle Wars: real-time multiplayer strategy","domain":"STRATEGY / GAME","type":"VideoGame","stage":"REALTIME PROTOTYPE","status":"lab","summary":"A multiplayer strategy game inspired by Tribal Wars 2. The prototype covers authentication, lobby, worlds, realtime, and the first resource-and-construction loop.","question":"Can synchronization and an initial economy sustain a fun multiplayer match?","scope":"Lobby, worlds, initial economy, and real-time multiplayer construction","role":"Frontend, authoritative server, and realtime protocol","capabilities":["frontend","backend","realtime"],"stack":["React","Node.js","Socket.IO","Firebase Auth"],"architecture":{"summary":"React client → Socket.IO gateway → Node.js world loop → Firebase authentication.","nodes":[{"code":"CLIENT","title":"World client","detail":"React / commands and projections"},{"code":"GATEWAY","title":"Realtime gateway","detail":"Socket.IO / rooms and presence"},{"code":"LOOP","title":"World process","detail":"Resources, queue, and server clock"},{"code":"STATE","title":"Persistence boundary","detail":"Memory now / explicit roadmap"}],"centralDecision":"Validate the realtime loop in memory and declare persistence as a gap instead of pretending the infrastructure is ready.","tradeoffs":[{"axis":"PROTOTYPE","choice":"In-memory state for the first loop","gain":"Validates synchronization and fun before operating larger infrastructure.","cost":"A restart loses the world and deliberately limits long sessions."},{"axis":"AUTHORITY","choice":"Command on client, decision on server","gain":"Economy and construction queue preserve a single source of truth.","cost":"The interface must account for latency, rejection, and reconciliation."},{"axis":"PROTOCOL","choice":"Small events per room","gain":"Updates stay focused on the world that actually changed.","cost":"Versioning and re-entry must rebuild a coherent snapshot."}],"executionTrace":{"trigger":"A player sends a command to begin construction.","steps":[{"code":"CLIENT","action":"Emits an intent with the known world version.","output":"build.requested"},{"code":"GATEWAY","action":"Authenticates presence, room, and event contract.","output":"command.accepted"},{"code":"LOOP","action":"Validates resources, queue, and clock on the authoritative server.","output":"build.started | rejected"},{"code":"STATE","action":"Advances the version and publishes the room projection.","output":"world.version + 1"}],"invariant":"Balance, clock, and queue are never changed directly by the client projection.","terminalState":"Every player receives the same version or an explicit rejection reason."}},"reliability":{"failureModes":["A client returns after a disconnect with a projection older than the server.","Two simultaneous commands compete for the same resource or queue slot.","A process restart invalidates the world still held in memory."],"candidateSignals":["Version difference between the client snapshot and authoritative state.","Commands rejected because of balance, clock, or queue conflict.","Reconnection rate that returns to the game without manual intervention."],"incidentDrills":[{"code":"DRILL-01","scenario":"A client returns after a disconnect with a projection older than the server.","containment":"Block new commands until the local version is compared with the authoritative room version.","recovery":"Deliver the current snapshot and event cursor, then reopen entry only after client acknowledgment.","proof":"Confirm every player sees the same world and no command was applied to an obsolete version."},{"code":"DRILL-02","scenario":"Two simultaneous commands compete for the same resource or queue slot.","containment":"Serialize the decision in the world process and reject the command that lost the version comparison.","recovery":"Publish the new projection and a rejection reason that lets the client reconstruct intent without guessing.","proof":"Run concurrent scenarios and demonstrate resource conservation, a valid queue, and monotonic versions."},{"code":"DRILL-03","scenario":"A process restart invalidates the world still held in memory.","containment":"Close the room as a lab session instead of pretending ephemeral state remains available.","recovery":"Create a new world and use the incident as a gate for checkpoints before persistent sessions.","proof":"Ensure no client resumes a ghost world and the prototype limit remains visible in the lobby."}]},"nextSignal":"Persist world state, add reconciliation, and test simultaneous command conflicts.","interviewAngles":["How to migrate an in-memory prototype to persistence without blocking the loop.","When to send an incremental event and when to rebuild a snapshot.","How to test clocks, economy, and concurrent conflicts deterministically."],"evidence":{"kind":"concept","image":"https://www.testaai.dev.br/media/castle-wars-concept.webp","alt":"Nighttime medieval map with castles, settlements, and green strategic routes."},"links":{"caseStudy":"https://www.testaai.dev.br/en/experiments/castle-wars"}},{"id":"auto-whats","index":"04","name":"Auto Whats","seoTitle":"Auto Whats: AI-powered WhatsApp automation","domain":"AUTOMATION / AI","type":"SoftwareApplication","stage":"SAAS ONLINE","status":"live","summary":"Connects WhatsApp by QR code, organizes the CRM, and uses business-aware AI to respond, qualify leads, schedule, follow up, and hand conversations to people.","question":"Can AI speed up service without hiding the human transition?","scope":"Support, CRM, WhatsApp sessions, automation, and human handoff","role":"Full-stack product, AI orchestration, and real-time operations","capabilities":["frontend","backend","data","realtime","ai","integrations"],"stack":["Next.js","Fastify","PostgreSQL","Redis","Baileys"],"architecture":{"summary":"Web console → Fastify API → Redis/PostgreSQL queues and state → WhatsApp session through Baileys.","nodes":[{"code":"CONSOLE","title":"Operator workspace","detail":"Next.js / inbox and CRM"},{"code":"SERVICE","title":"Conversation API","detail":"Fastify / policies and commands"},{"code":"STATE","title":"Queues + storage","detail":"Redis / PostgreSQL"},{"code":"CHANNEL","title":"WhatsApp + AI","detail":"Baileys / model / handoff"}],"centralDecision":"Treat AI as a per-conversation controllable mode and keep human handoff as a first-class product path.","tradeoffs":[{"axis":"CONTROL","choice":"Per-conversation AI mode","gain":"The operator can take over without competing with automated replies.","cost":"Every queue must immediately honor the authority change."},{"axis":"STATE","choice":"Redis for transit, Postgres for memory","gain":"Low latency does not turn ephemeral state into permanent history.","cost":"Retries and reconciliation cross two operational layers."},{"axis":"AI","choice":"Model proposes; policy decides","gain":"Qualification and replies accelerate inside auditable boundaries.","cost":"Context, validation, and metrics cost more than a direct call."}],"executionTrace":{"trigger":"A new message arrives through a connected WhatsApp session.","steps":[{"code":"CHANNEL","action":"Normalizes, correlates, and removes known redelivery.","output":"message.received"},{"code":"SERVICE","action":"Resolves conversation owner, policy, and AI eligibility.","output":"reply | handoff | hold"},{"code":"STATE","action":"Persists context and queues only the effect that remains valid.","output":"work.scheduled"},{"code":"CONSOLE","action":"Updates inbox, CRM, and decision reason for the operator.","output":"conversation.projected"}],"invariant":"Only the current conversation owner can authorize an outgoing reply.","terminalState":"Message, decision, handoff, and effect share an auditable correlation."}},"reliability":{"failureModes":["The WhatsApp session disconnects during a support sequence.","A message is redelivered and duplicates a CRM or follow-up effect.","Automation replies after the conversation has been handed to a person."],"candidateSignals":["Recovery time and stability of connected sessions.","Handoff reason, human correction, and workflow resumption.","Duplicated, delayed, blocked, or unconfirmed messages."],"incidentDrills":[{"code":"DRILL-01","scenario":"The WhatsApp session disconnects during a support sequence.","containment":"Mark the channel unavailable, limit the queue, and prevent replies that appear confirmed to the operator.","recovery":"Reauthenticate the session, resume from the last acknowledgment, and reconcile messages by channel identifier.","proof":"Confirm a stable connection, a backlog drained once, and a conversation projected in the acknowledged order."},{"code":"DRILL-02","scenario":"A message is redelivered and duplicates a CRM or follow-up effect.","containment":"Deduplicate by external identifier and reuse each derived effect's idempotency key.","recovery":"Reconcile receipt, message, and CRM action before releasing any still-unconfirmed retry.","proof":"Demonstrate one logical message, one CRM effect, and one confirmation despite multiple deliveries."},{"code":"DRILL-03","scenario":"Automation replies after the conversation has been handed to a person.","containment":"Increment the authority version and invalidate jobs whose expected owner is no longer AI.","recovery":"Project the handoff in the console, keep the human as sole sender, and discard stale proposals.","proof":"Run interleaving tests and confirm no stale output crosses the authority change."}]},"nextSignal":"Expand quality metrics, context recovery, and operational guarantees for connected sessions.","interviewAngles":["How to ensure a handoff invalidates already queued work.","Which context to send the model and which state never to entrust to it.","How to observe quality without retaining sensitive conversations indefinitely."],"evidence":{"kind":"build-artifact","image":"https://www.testaai.dev.br/media/autowhats-field.webp","alt":"Auto Whats dashboard with CRM, demonstration conversations, and global AI controls."},"links":{"caseStudy":"https://www.testaai.dev.br/en/experiments/auto-whats","publicDeployment":"https://auto-whats.vercel.app/pt"}},{"id":"ai-vtt","index":"05","name":"AI_VTT","seoTitle":"AI_VTT: a virtual tabletop with an AI game master","domain":"RPG / GENERATIVE GAME","type":"VideoGame","stage":"VERTICAL SLICE","status":"lab","summary":"A solo or two-player virtual tabletop with a persistent lobby, exploration, and combat. The AI game master works through text or voice without controlling the rules.","question":"Can an AI run the story without taking over the rules?","scope":"Shared tabletop, persistent campaign, rules, narration, and voice","role":"Full-stack architecture, realtime, and generative AI with guardrails","capabilities":["frontend","backend","data","realtime","ai"],"stack":["TypeScript","PostgreSQL","Voice AI","Rules engine"],"architecture":{"summary":"Shared tabletop → rules and state engine → narrative context → AI game master by text or voice.","nodes":[{"code":"TABLE","title":"Shared tabletop","detail":"Map, turn, dice, and presence"},{"code":"RULES","title":"Authoritative engine","detail":"Actions, movement, and combat"},{"code":"MEMORY","title":"Campaign state","detail":"PostgreSQL / cursor and snapshot"},{"code":"GM.AI","title":"Narrative layer","detail":"Context, text, voice, and fallback"}],"centralDecision":"Separate probabilistic narration from deterministic resolution; AI proposes fiction and the system validates actions.","tradeoffs":[{"axis":"AUTHORITY","choice":"Rules outside the model","gain":"Fiction can improvise without changing dice, health, or inventory.","cost":"Narrative must translate engine rejections naturally."},{"axis":"CONTEXT","choice":"Campaign cursor + snapshot","gain":"Recovery does not require resending the entire session history.","cost":"Summary and state must evolve without contradicting past events."},{"axis":"INTERACTION","choice":"Voice with text fallback","gain":"The table remains operable when synthesis, network, or model is slow.","cost":"Multimodal turns require careful cancellation and coordination."}],"executionTrace":{"trigger":"A player proposes an action during their turn at the shared table.","steps":[{"code":"TABLE","action":"Captures intent, actor, target, and observed version.","output":"action.proposed"},{"code":"RULES","action":"Validates turn, range, roll, and deterministic consequence.","output":"action.resolved | rejected"},{"code":"MEMORY","action":"Persists the event and derives the new campaign snapshot.","output":"campaign.advanced"},{"code":"GM.AI","action":"Narrates the confirmed outcome through text or voice.","output":"narration.emitted"}],"invariant":"The narrative layer never confirms health, position, inventory, or dice on its own.","terminalState":"Rule event and narration point to the same cause and campaign version."}},"reliability":{"failureModes":["The game master narrates a consequence the rules engine did not authorize.","Players reconnect with different versions of the shared campaign.","Voice latency or interruption leaves a turn without a clear owner."],"candidateSignals":["Narrative proposals rejected or corrected by the rules engine.","Consistency between the recovered snapshot and last confirmed event.","Per-turn latency and frequency of voice-to-text fallback."],"incidentDrills":[{"code":"DRILL-01","scenario":"The game master narrates a consequence the rules engine did not authorize.","containment":"Interrupt divergent narration and preserve the deterministic event as the only state authority.","recovery":"Generate a correction or text fallback from the confirmed result without changing health or inventory.","proof":"Validate that narration, event, and snapshot point to the same version and rule consequence."},{"code":"DRILL-02","scenario":"Players reconnect with different versions of the shared campaign.","containment":"Reject new proposals until each participant acknowledges the current campaign cursor.","recovery":"Send the snapshot plus later events and rebuild table, turn, and presence before reopening actions.","proof":"Compare the recovered state version and hash across server and every connected player."},{"code":"DRILL-03","scenario":"Voice latency or interruption leaves a turn without a clear owner.","containment":"Cancel pending synthesis, freeze automatic turn passage, and display the confirmed result as text.","recovery":"Return control to the current player and begin new narration only with a current turn token.","proof":"Confirm a single turn transition, no late audio, and continuity through the text fallback."}]},"nextSignal":"Test long-running campaign recovery, voice latency, and narrative consistency in two-player sessions.","interviewAngles":["How to compose campaign context without turning history into authority.","How to synchronize two players and an agent that also produces events.","How to evaluate narrative quality separately from rule correctness."],"evidence":{"kind":"build-artifact","image":"https://www.testaai.dev.br/media/ai-vtt-field.webp","alt":"Four people play a fantasy tabletop RPG with miniatures, dice, and teal lighting."},"links":{"caseStudy":"https://www.testaai.dev.br/en/experiments/ai-vtt"}},{"id":"desafio-online","index":"06","name":"Desafio Online","seoTitle":"Desafio Online: collaborative team puzzles","domain":"PUZZLE / SOCIAL GAME","type":"VideoGame","stage":"PLAYABLE MVP","status":"live","summary":"A platform for pairs and groups with teams, invitations, and persistent expeditions. The Impossible Map combines clues, timed hints, and shared progress.","question":"Can different clues become a memorable social competition?","scope":"Teams, invitations, clues, timed hints, and shared progress","role":"Full-stack product, game modeling, and transactional persistence","capabilities":["frontend","backend","data","integrations"],"stack":["Next.js 16","React 19","PostgreSQL","Drizzle","Firebase Auth"],"architecture":{"summary":"Expedition interface → server-side team actions → persistent PostgreSQL progress → Firebase identity.","nodes":[{"code":"EXPEDITION","title":"Team interface","detail":"Next.js / map and clues"},{"code":"COMMAND","title":"Server actions","detail":"Submission, hint, and readiness"},{"code":"PROGRESS","title":"Game state","detail":"PostgreSQL + Drizzle"},{"code":"IDENTITY","title":"Access boundary","detail":"Firebase Auth / invitations"}],"centralDecision":"Keep solutions and progression authoritative on the server; the browser receives only the state required for the current stage.","tradeoffs":[{"axis":"SECRET","choice":"Answers only on the server","gain":"The client never receives the solution before clue validation.","cost":"Preview and offline modes remain deliberately limited."},{"axis":"TEAM","choice":"Authoritative shared progress","gain":"Everyone sees the same expedition, hint, and completion order.","cost":"Simultaneous actions need idempotency and explicit conflict handling."},{"axis":"CONTENT","choice":"Clues as composable mechanisms","gain":"An expedition combines logic, media, and interaction without one screen per game.","cost":"The editorial schema must limit complexity and validate each type."}],"executionTrace":{"trigger":"A member submits an answer to the team's current clue.","steps":[{"code":"IDENTITY","action":"Confirms identity, invitation, and expedition membership.","output":"member.authorized"},{"code":"COMMAND","action":"Normalizes the attempt without returning the expected solution.","output":"answer.checked"},{"code":"PROGRESS","action":"Records the attempt or advancement in an idempotent transaction.","output":"progress.version + 1"},{"code":"EXPEDITION","action":"Projects clue, timer, and shared state to the team.","output":"team.synchronized"}],"invariant":"The correct answer and future content never cross the payload sent to the browser.","terminalState":"Every member sees the same version, hint, and expedition position."}},"reliability":{"failureModes":["Two people submit the correct solution at the same instant.","The hint clock diverges after suspension or a device change.","An answer or future clue appears in the browser payload."],"candidateSignals":["Completion time and hint-use rate by clue mechanism.","Idempotent conflicts and recovery without progress regression.","Accepted invitations, ready teams, and expeditions actually started."],"incidentDrills":[{"code":"DRILL-01","scenario":"Two people submit the correct solution at the same instant.","containment":"Compare and update the expedition version inside one transaction, accepting a single advancement.","recovery":"Respond to the second command with the already-advanced state, without treating it as a new completion or penalty.","proof":"Demonstrate one advancement event, one next position, and an invariant ranking under concurrent repetition."},{"code":"DRILL-02","scenario":"The hint clock diverges after suspension or a device change.","containment":"Ignore client clocks and calculate eligibility only from the server-persisted deadline.","recovery":"Resend reference instant, deadline, and current state when the team resumes the expedition.","proof":"Simulate different local clocks and confirm the same hint release for the whole team."},{"code":"DRILL-03","scenario":"An answer or future clue appears in the browser payload.","containment":"Block the affected route and immediately remove the secret field from the client contract.","recovery":"Move validation and resolution to the server, invalidate caches, and build a new artifact without the solution.","proof":"Inspect HTML, RSC, JavaScript, and network to confirm future content never crosses the public boundary."}]},"nextSignal":"Instrument clue difficulty and completion rankings, then build editorial tools for new expeditions.","interviewAngles":["How to create new clue types without spreading conditionals across the product.","How to define a fair ranking when network and team actions vary.","How to test secret content without letting it reach the client bundle."],"evidence":{"kind":"build-artifact","image":"https://www.testaai.dev.br/media/nexo-field.webp","alt":"NEXO poster: an encoded-treasure message beside a map with a route and puzzle symbols."},"links":{"caseStudy":"https://www.testaai.dev.br/en/experiments/desafio-online","publicDeployment":"https://nexo-desafios.vercel.app/"}},{"id":"our-home","index":"07","name":"Our Home","seoTitle":"Our Home: shared household organization on iPhone","domain":"MOBILE / HOUSEHOLD","type":"SoftwareApplication","stage":"iOS MVP 1.0","status":"lab","summary":"An iPhone app where couples and families share shopping, recurring tasks, and responsibilities with real-time synchronization.","question":"Does routine feel lighter when shopping, tasks, and context live in one place?","scope":"Shared shopping, recurring tasks, residents, and invitations on iPhone","role":"Full-stack mobile product, relational modeling, and multi-tenant security","capabilities":["frontend","backend","data","realtime","integrations"],"stack":["Expo SDK 57","React Native","TypeScript","Supabase","PostgreSQL"],"architecture":{"summary":"React Native app → Supabase commands and channels → PostgreSQL with RLS, RPCs, and triggers → synchronized household projection.","nodes":[{"code":"APP","title":"iOS client","detail":"Expo / React Native / TypeScript"},{"code":"SYNC","title":"Realtime projection","detail":"Supabase channels / refresh"},{"code":"DOMAIN","title":"Database commands","detail":"RPCs, triggers, and recurrence"},{"code":"DATA","title":"Household boundary","detail":"PostgreSQL / Auth / RLS"}],"centralDecision":"Keep authorization and critical transitions close to the database; the app sends intents and reconciles the projection through Realtime.","tradeoffs":[{"axis":"AUTHORIZATION","choice":"RLS and critical commands close to the database","gain":"The household boundary remains valid outside the mobile interface.","cost":"Migrations, grants, RPCs, and policies must evolve and be tested together."},{"axis":"SYNC","choice":"Event invalidates; client reloads projection","gain":"The MVP avoids rebuilding every concurrent mutation locally.","cost":"Convergence performs extra reads and depends on well-handled recovery."},{"axis":"SCOPE","choice":"One active household in the initial interface","gain":"Creation, invitation, and routine reach use before a broader selector.","cost":"The database supports multiple households, but navigation between them is deferred."}],"executionTrace":{"trigger":"A resident marks a recurring task complete on iPhone.","steps":[{"code":"APP","action":"Sends the intent with task, new status, and authenticated session.","output":"status.requested"},{"code":"DOMAIN","action":"The RPC validates household membership and applies the transition.","output":"status.changed | denied"},{"code":"DATA","action":"Triggers record author and time and calculate the next occurrence.","output":"history.appended"},{"code":"SYNC","action":"The event invalidates the projection and each resident reloads household state.","output":"household.converged"}],"invariant":"A session only reads or changes households it belongs to; every status change preserves authorship or automated origin.","terminalState":"Residents see the same persisted status, assignee, and next occurrence."}},"reliability":{"failureModes":["Invitation and removal of the same resident happen almost simultaneously.","A monthly task completed near a time-zone boundary reopens on the wrong date.","The app misses events while suspended on iPhone."],"candidateSignals":["Time between a change and convergence across devices in the same household.","RLS denials and failures by RPC, table, and resident role.","Recurrences reopened on the correct date by frequency and time zone."],"incidentDrills":[{"code":"DRILL-01","scenario":"Invitation and removal of the same resident happen almost simultaneously.","containment":"Serialize database entry, revoke invitations for the removed person, and check the block before creating membership.","recovery":"Keep the account outside the household and require an explicit administrative decision for future unblocking.","proof":"Repeat the transactional race and confirm no membership, a persisted block, and revoked codes."},{"code":"DRILL-02","scenario":"A monthly task completed near a time-zone boundary reopens on the wrong date.","containment":"Preserve the current occurrence and stop rollovers derived from an inconsistent time reference.","recovery":"Recalculate the next date on the server from the persisted rule and resume the task once.","proof":"Run time-zone, month, and year boundary cases and verify status, next_due_at, and the automated event."},{"code":"DRILL-03","scenario":"The app misses events while suspended on iPhone.","containment":"Do not assume the in-memory projection remains current after an app-state change.","recovery":"Revalidate session and context on return to active, then reload members, shopping, and tasks.","proof":"Change the household on another device during suspension and confirm convergence after recovery."}]},"nextSignal":"Validate version 1.0 on physical iPhones before adding notifications and a shared calendar.","interviewAngles":["How to design RLS and RPCs so the multi-tenant boundary does not depend on the client.","When to replace invalidation plus refresh with incremental events or offline-first state.","How to test recurrence, invitation concurrency, and mobile recovery without relying on the real clock."],"evidence":{"kind":"build-artifact","image":"https://www.testaai.dev.br/media/our-home-field.webp","alt":"Our Home demo on an iPhone with a summary and shared household task cards."},"links":{"caseStudy":"https://www.testaai.dev.br/en/experiments/our-home"}}],"writing":[{"id":"interface-impressionante-sem-spa-inteiro","title":"How to create an impressive interface without shipping a full SPA","seoTitle":"An impressive interface without shipping a full SPA","category":"Frontend","tags":["web performance","progressive enhancement","React","accessibility"],"readingMinutes":7,"wordCount":1402,"publishedAt":"2026-08-22T07:35:00-03:00","modifiedAt":"2026-08-22T07:35:00-03:00","url":"https://www.testaai.dev.br/en/blog/impressive-interface-without-a-full-spa"},{"id":"handoff-humano-em-automacoes-com-ia","title":"Human handoff in AI automation: authority before the reply","seoTitle":"Human handoff in AI automation","category":"Architecture","tags":["applied AI","system design","concurrency","WhatsApp"],"readingMinutes":6,"wordCount":1277,"publishedAt":"2026-08-22T07:15:00-03:00","modifiedAt":"2026-08-22T07:15:00-03:00","url":"https://www.testaai.dev.br/en/blog/human-handoff-in-ai-automations"},{"id":"ia-com-limites-arquitetura-antes-do-prompt","title":"AI with boundaries: why architecture comes before the prompt","seoTitle":"AI with boundaries: architecture before the prompt","category":"Software engineering","tags":["artificial intelligence","software architecture","guardrails","system design"],"readingMinutes":6,"wordCount":1101,"publishedAt":"2026-08-22T06:55:00-03:00","modifiedAt":"2026-08-22T06:55:00-03:00","url":"https://www.testaai.dev.br/en/blog/ai-with-boundaries-architecture-before-the-prompt"},{"id":"como-validar-uma-ideia-de-software","title":"How to validate a software idea before building everything","seoTitle":"Validate a software idea before building everything","category":"Product","tags":["product validation","software","MVP","experiments"],"readingMinutes":5,"wordCount":917,"publishedAt":"2026-08-22T06:40:00-03:00","modifiedAt":"2026-08-22T06:40:00-03:00","url":"https://www.testaai.dev.br/en/blog/how-to-validate-a-software-idea"},{"id":"construir-em-publico-sem-vender-certezas","title":"Building in public without turning the process into a spectacle","seoTitle":"Building in public without selling certainty","category":"Building in public","tags":["build in public","product","transparency","learning"],"readingMinutes":4,"wordCount":684,"publishedAt":"2026-08-22T06:10:00-03:00","modifiedAt":"2026-08-22T06:10:00-03:00","url":"https://www.testaai.dev.br/en/blog/building-in-public-without-selling-certainty"}],"implementation":{"rendering":"Static pages + React Server Components","interaction":"Progressive enhancement; core content works before client JavaScript","accessibility":["Keyboard navigation","Reduced motion and slow update support","Increased contrast and forced colors support","Print-specific recruiter brief"],"privacy":{"analytics":false,"cookies":false,"remoteFonts":false,"backgroundConnections":false},"quality":{"snapshot":{"canonicalPageCount":36,"contrastPairCount":84,"interactionModuleCount":9,"ownInteractionKilobytes":27.7,"trackerCount":0,"lintWarningBudget":0,"measured":{"totalClientJavaScriptGzipKilobytes":152.8,"cssGzipKilobytes":31.3,"localFontKilobytes":32.9,"serverKilobytes":1508.3},"budgets":{"ownInteractionKilobytes":28,"totalClientJavaScriptGzipKilobytes":156,"cssGzipKilobytes":32,"localFontKilobytes":35,"serverKilobytes":1600}},"gates":[{"code":"TYPE SYSTEM","value":"STRICT","title":"TypeScript as a contract","text":"Strict types, exact optionals, and defensive indexed access block ambiguity before the build."},{"code":"STATIC ANALYSIS","value":"0 WARN","title":"Lint without amnesty","text":"ESLint and JSX/ARIA rules fail on errors and warnings alike; accessibility is never postponed."},{"code":"CONTRAST","value":"84 AA","title":"Measured readability","text":"Audited information pairs pass WCAG AA, with dedicated adaptations for contrast and forced colors."},{"code":"PRIVACY","value":"0 TRACK","title":"No hidden observer","text":"No analytics, cookie, remote font, or background connection enters the institutional experience."},{"code":"INTERACTION","value":"27.7 KB","title":"Bounded complexity","text":"Nine custom modules remain isolated and below the 28 KB budget; useful content arrives first."},{"code":"DISCOVERY","value":"36 URL","title":"Findable and readable","text":"Sitemap, JSON-LD, RSS, canonicals, and JSON Schema connect pages, cases, writing, authorship, and contract."}],"deliveryPipeline":[{"code":"ROUTE","title":"Page contract","text":"Metadata, semantic content, and JSON-LD are born with the route and never depend on hydration.","output":"RSC + HTML"},{"code":"BUILD","title":"Static compilation","text":"Vinext and Vite resolve pages, styles, and modules before release; the sanitizer inspects the output.","output":"DIST / CLEAN"},{"code":"DELIVERY","title":"Versioned payload","text":"CSS, JavaScript, and fonts receive immutable names; responsive media keeps explicit dimensions and its own cache.","output":"CACHE / HASH"},{"code":"ENHANCE","title":"Interaction attached later","text":"Nine small islands add search, movement, and controls without taking ownership of the main content.","output":"09 ISLANDS"}],"interactionModules":[{"name":"SignalField","purpose":"generative canvas field","fallback":"static visual composition"},{"name":"ParticleLogo","purpose":"reactive particle mark","fallback":"static, readable wordmark"},{"name":"LabInterface","purpose":"progress, TOC, and spotlight","fallback":"anchors and linear reading"},{"name":"CommandPalette","purpose":"keyboard search and jump","fallback":"native navigation and links"},{"name":"EngineeringConsole","purpose":"tabbed technical lenses","fallback":"readable first lens"},{"name":"ProjectLens","purpose":"capability filter","fallback":"complete catalog"},{"name":"BlueprintToggle","purpose":"visual grid inspection","fallback":"standard editorial interface"},{"name":"CopyLink","purpose":"contextual URL copy","fallback":"navigable canonical URL"},{"name":"PrintBrief","purpose":"print/PDF shortcut","fallback":"native browser printing"}],"adaptiveModes":[{"signal":"prefers-reduced-motion","response":"continuous movement and decorative transitions stop"},{"signal":"update: slow","response":"canvas and animations follow the same economical path as reduced motion"},{"signal":"prefers-reduced-transparency","response":"surfaces receive opaque backgrounds and more explicit borders"},{"signal":"prefers-contrast: more","response":"secondary text and separators receive additional contrast"},{"signal":"forced-colors: active","response":"system colors replace effects that do not carry information"},{"signal":"print","response":"the briefing becomes an A4 document without unnecessary navigation or decoration"}],"architectureDecisions":[{"id":"ADR-001","status":"ACCEPTED","title":"Static route, explicit islands","context":"The portfolio needed to combine long-form narrative, search discovery, and interactive tools without turning every page into a client application.","decision":"Pre-render content and metadata in Server Components; hydrate only nine modules with narrow responsibilities and named fallbacks.","rejected":"A single SPA would simplify global state, but reading, navigation, and indexing would depend on a larger client boundary.","consequence":"Composition requires contracts between HTML and islands, but content, links, and structure remain useful before JavaScript.","proof":"STATIC HTML / 09 ISLANDS / NO-JS FALLBACKS"},{"id":"ADR-002","status":"ACCEPTED","title":"Motion constrained by the environment","context":"Particles and transitions help communicate a technology lab, but they can compete with reading, battery, CPU, and visitor preferences.","decision":"Use a deterministic 2D canvas with capped density and DPR, visibility and intersection pauses, and reduced modes driven by preferences.","rejected":"WebGL and a 3D scene would increase spectacle at a disproportionate cost for a layer that carries no essential information.","consequence":"The effect is intentionally less cinematic, but it recedes predictably and never changes hierarchy or navigation.","proof":"BOUNDED CANVAS / DPR CAP / ADAPTIVE MOTION"},{"id":"ADR-003","status":"ACCEPTED","title":"Native primitives before custom controls","context":"Dense cases must progressively reveal detail without hiding content from keyboards, assistive technology, or non-hydrated environments.","decision":"Prioritize links, anchors, tables, meter, details, and summary; add client behavior only when the primitive cannot solve the task.","rejected":"Fully custom accordions and meters would offer more visual control but recreate focus, state, and semantics already available in the browser.","consequence":"Some nuances vary across browsers; in exchange, the basic path stays operable, recognizable, and easy to audit.","proof":"NATIVE DISCLOSURE / SEMANTIC METER / KEYBOARD PATH"},{"id":"ADR-004","status":"ACCEPTED","title":"Public inspection without hidden observation","context":"Recruiters, readers, and crawlers need to verify authorship, projects, and quality, while an institutional portfolio does not need behavioral surveillance.","decision":"Publish portfolio.json, RSS, sitemap, and humans.txt with tested contracts; keep analytics, cookies, remote fonts, and pixels off the origin.","rejected":"Third-party telemetry would answer audience questions but add identity, network, and data-policy costs without improving technical evaluation.","consequence":"There is no automatic behavioral funnel. Evidence comes from the artifact, its checks, and conversations initiated by people inspecting it.","proof":"PUBLIC CONTRACTS / 0 TRACKERS / SAME-ORIGIN CSP"}],"securityBoundaries":[{"code":"EXECUTION","title":"Closed origin, explicit bootstrap","text":"CSP keeps files on the same origin and blocks executable attributes; the runtime-required inline bootstrap remains a documented cost."},{"code":"EMBEDDING","title":"A surface that cannot be framed","text":"Frame ancestors, frame source, and X-Frame-Options prevent silent third-party embedding."},{"code":"CAPABILITIES","title":"Permissions denied by default","text":"Camera, microphone, geolocation, payments, USB, and browsing topics remain disabled."},{"code":"PRIVACY","title":"No hidden observation","text":"No cookies, analytics, remote fonts, pixels, or background connections in the institutional portfolio."}],"verificationPipeline":[{"index":"01","title":"Contract","commands":"schema / content / SEO / docs","result":"instance, data, and discovery synchronized"},{"index":"02","title":"Static","commands":"TypeScript / ESLint / contrast","result":"zero errors and zero warnings"},{"index":"03","title":"Media","commands":"fidelity / hashes / rollback","result":"derivatives intact and recoverable"},{"index":"04","title":"Build","commands":"Vinext / sanitizer / budgets","result":"clean artifact within limits"},{"index":"05","title":"Runtime","commands":"HTTP / semantics / headers","result":"routes and policies verified"},{"index":"06","title":"Edge","commands":"public links / npm audit","result":"dependencies and ports checked"}],"buildHistory":[{"cut":"CUT. 01","date":"2026-08-21","title":"The brand became an interface","text":"Palette, Sora, flask, and laboratory language became a responsive editorial composition.","proof":"TOKENS / ICONS / STATIC ROUTES"},{"cut":"CUT. 02","date":"2026-08-21","title":"The manifesto became a system","text":"Home, Experiments, and Zero were separated; blog, sitemap, RSS, and structured data opened discovery.","proof":"MULTI-PAGE / SEO / WRITING"},{"cut":"CUT. 03","date":"2026-08-22","title":"The showcase became evidence","text":"Cases gained maps, trade-offs, traces, failures, and a printable recruiter briefing.","proof":"07 CASES / BRIEF / COMMANDS"},{"cut":"CUT. 04","date":"2026-08-22","title":"Evidence gained a contract","text":"Real budgets, incident drills, machine-readable surfaces, and the build itself became inspectable.","proof":"QUALITY / RESILIENCE / JSON"}],"dossier":"https://www.testaai.dev.br/en/engineering"}},"editorialNotice":"Stack and functional scope were checked against available sources. Impact metrics, hypotheses, stages and candidate signals remain editorial until replaced by measured evidence.","links":{"canonical":"https://www.testaai.dev.br/en","recruiterBrief":"https://www.testaai.dev.br/en/briefing","engineeringDossier":"https://www.testaai.dev.br/en/engineering","experiments":"https://www.testaai.dev.br/en/experiments","profile":"https://www.testaai.dev.br/en/zero","blog":"https://www.testaai.dev.br/en/blog","rss":"https://www.testaai.dev.br/en/feed.xml","humans":"https://www.testaai.dev.br/en/humans.txt","llms":"https://www.testaai.dev.br/en/llms.txt","portfolioSchema":"https://www.testaai.dev.br/en/portfolio.schema.json"}}