Oracle3
Open-source trading engine and MCP server for prediction markets. Fee-aware no-arbitrage trading across related contracts, live on Kalshi, Polymarket and Solana or on paper.
Personal finances, made simple.
Translation pending
FinanceTypeScript · PLpgSQLGitHub @CristianPerez06OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
Aplicación de finanzas personales. Si no tenés pnpm instalado todavía, elegí una de estas opciones: • Rápido (recomendado si tenés Node ≥ 16.13): • Canónico: seguir las instrucciones de pnpm.io/installation.Read the full README ↗
Aplicación de finanzas personales.
Si no tenés pnpm instalado todavía, elegí una de estas opciones:
corepack enable pnpm
Verificá que quedó disponible:
pnpm --version
pnpm install
Si ves un warning tipo
[ERR_PNPM_IGNORED_BUILDS]mencionando paquetes como@parcel/watchero@swc/core, no es un error: pnpm pide tu autorización explícita para correr los build scripts de esas dependencias (es una protección contra paquetes maliciosos). En este repo ya dejamos preaprobados los paquetes seguros en la secciónpnpm.onlyBuiltDependenciesdepackage.json, así que normalmente no debería aparecer. Si igual aparece (por ejemplo después de agregar una dependencia nueva), corré:pnpm approve-buildsTe va a abrir un menú interactivo: con la barra espaciadora seleccionás los paquetes a aprobar y con Enter confirmás. Para los paquetes que ya están en el proyecto (
@parcel/watcher,@swc/core) es seguro aprobarlos.
Copia el archivo de ejemplo y completa tus credenciales de Supabase:
cp apps/web/.env.example apps/web/.env
Next.js carga el
.envdesde el cwd de la app, por eso vive enapps/web/, no en la raíz del repo.
| Variable | Dónde encontrarla |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | Panel de Supabase → Project Settings → API → Project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Panel de Supabase → Project Settings → API → Publishable key |
Antes de levantar la app por primera vez, en el panel de Supabase:
Authentication → Providers → Email
Authentication → URL Configuration
http://localhost:3000 en desarrollo, tu dominio en producción.http://localhost:3000/auth/callbackhttps://<tu-dominio>/auth/callback (cuando despliegues)Authentication → Email Templates
Los templates viven versionados en el repo bajo supabase/templates/. El repo es la source of truth — el dashboard de Supabase es un mirror manual: mantenerlo al día es un paso que hace una persona, cada vez. Los asuntos de los mails, en cambio, hoy viven sólo en el dashboard: no están versionados acá.
Para cada uno de estos dos templates, abrí el archivo del repo, copiá el contenido completo del body y pegalo en el campo correspondiente del dashboard:
| Template del dashboard | Archivo en el repo |
|---|---|
| Confirm signup | supabase/templates/confirm-signup.html |
| Reset password | supabase/templates/reset-password.html |
Como doble check, los enlaces dentro de cada template deben respetar estas formas exactas (el callback de la app las parsea con esa estructura):
confirm-signup → {{ .SiteURL }}/auth/callback?token_hash={{ .TokenHash }}&type=signup
reset-password → {{ .SiteURL }}/auth/callback?code={{ .Token }}&next=/reset-password
Si el dashboard y el repo divergen alguna vez, sobrescribí el dashboard con el contenido del repo, nunca al revés. Los subjects (asuntos) por ahora siguen viviendo solo en el dashboard.
Ejecutar en SQL Editor:
# El archivo está en supabase/migrations/0001_profiles.sql
Copiar y pegar el contenido del archivo; correrlo una vez. Crea la tabla public.profiles, su RLS y el trigger on_auth_user_created que la mantiene sincronizada con auth.users.
pnpm dev
La app estará disponible en http://localhost:3000.
El repo está configurado para usar OpenSpec como flujo de spec-driven development. Los skills y slash commands ya vienen versionados en .claude/ (Claude Code) y .agents/ (Codex), pero el CLI se instala aparte:
pnpm add -g @fission-ai/openspec
Una vez instalado, dentro de Claude Code podés usar:
/grana-lightweight-explore — pensar / refinar una idea antes de proponerla: corto y sin escribir nada/grana-deep-explore — el /opsx:explore original de OpenSpec, palabra por palabra: largo, con diagramas, y puede escribir artefactos de OpenSpec si le decís que sí/opsx:propose "<idea>" — crear una nueva propuesta de cambio/opsx:apply — implementar las tasks de un cambio/opsx:update — revisar los artefactos de un cambio ya propuesto/opsx:sync — bajar las deltas del cambio a las specs maestras/opsx:archive — archivar un cambio ya completadoLas propuestas viven en openspec/changes/ y las specs en openspec/specs/.
Los comandos sin sufijo apuntan a apps/web. Para mobile usá los sufijos :mobile o pnpm --filter mobile <script>.
| Script | Descripción |
|---|---|
pnpm dev | Inicia el servidor de desarrollo de web |
pnpm build | Compila la app web para producción |
pnpm start | Ejecuta la build de producción de web |
pnpm lint | Ejecuta ESLint sobre apps/web |
pnpm typecheck | Type-check de apps/web |
pnpm test | Tests (Vitest) de apps/web |
pnpm storybook | Levanta Storybook en el puerto 6006 (web) |
pnpm dev:mobile | Inicia Expo dev server |
pnpm lint:mobile | Lint de apps/mobile |
pnpm typecheck:mobile | Type-check de apps/mobile |
pnpm eas:android | Build de Android con EAS (remoto) |
pnpm eas:ios | Build de iOS con EAS (remoto) |
pnpm openspec:check | Valida que ningún spec maestro tenga Purpose: TBD residual |
pnpm check:openspec-workflows | Valida que los workflows generados por OpenSpec sigan siendo cinco |
pnpm check:duplicate-deps | Falla si react o react-native quedaron duplicados en el workspace |
pnpm check:test-timezone | Falla si algún script test no corre en la zona horaria financiera |
pnpm verify | Todo lo que corre CI y se puede correr local, en un comando |
apps/web/components/ui/ con su Storybook story al lado. Antes de inventar un wrapper compuesto, ver si se puede componer con los primitivos existentes.bg-background, text-foreground, text-destructive, etc.). Los tokens viven en packages/ui-tokens/src/theme.css y apps/web/app/globals.css los importa. Nada de bg-zinc-*/text-gray-* directos — rompen el dark mode.next-intl con cookie NEXT_LOCALE (sin segmento [locale] en la URL). Los locales soportados están en apps/web/lib/i18n/config.ts; los catálogos en packages/i18n-messages/src/<locale>.json (consumidos vía @grana/i18n-messages). El switcher vive en el footer.packages/validation/src/ (paquete @grana/validation), compartidos entre los forms (react-hook-form + yupResolver) y los server actions (validateActionInput). El bridge React/next-intl (setup-yup-locale.tsx) se queda en apps/web/lib/validation/ porque depende del runtime de next-intl.packages/supabase/ (paquete @grana/supabase, expone createClient + slot Database). Los wrappers Next-aware (createBrowserClient / createServerClient con cookies de @supabase/ssr) viven en apps/web/lib/supabase/.ActionResult<T> = { ok: true } | { ok: false, fieldErrors?, formError? }. Los errores se muestran en la ruta con estado local, no por querystring.El repo es un monorepo pnpm con dos apps: web (apps/web, Next.js App Router) y mobile (apps/mobile, Expo). Comparten datos en Supabase y código vía los paquetes packages/*.
grana-v3/
├── apps/
│ ├── web/ # Next.js App Router
│ │ ├── app/ # rutas, layouts, server actions
│ │ ├── components/ # primitivos UI (HTML) + features web
│ │ ├── lib/ # código específico de web (supabase ssr, i18n runtime, etc.)
│ │ ├── .storybook/
│ │ ├── public/ # activos estáticos
│ │ ├── .env / .env.example # vars de entorno (Next las lee desde el cwd de la app)
│ │ ├── next.config.ts # `transpilePackages` incluye los @grana/*
│ │ └── tsconfig.json # extiende `../../tsconfig.base.json`
│ └── mobile/ # Expo (React Native) — espejo funcional del web
│ ├── app/ # rutas Expo Router
│ ├── components/ # primitivos UI (RN) + features mobile
│ ├── lib/ # código específico de mobile (supabase client RN, i18n RN)
│ └── app.json # config de Expo
├── packages/
│ ├── validation/ # @grana/validation — schemas Yup + helpers (cross-platform)
│ ├── i18n-messages/ # @grana/i18n-messages — catálogos JSON
│ ├── supabase/ # @grana/supabase — slot Database + createClient factory
│ ├── ui-tokens/ # @grana/ui-tokens — design tokens (CSS variables, web + mobile)
│ └── dashboard/ # @grana/dashboard — queries + agregaciones del dashboard
├── supabase/ # SQL migrations + email templates (backend, no es una app)
├── openspec/ # workflow spec-driven
├── AGENTS.md # instrucciones canónicas para LLMs (Claude Code, Codex, Cursor, …)
├── CLAUDE.md # stub que apunta a AGENTS.md (compat con tooling que carga CLAUDE.md)
├── SUPABASE_SETUP.md
├── README.md
├── package.json # orquestador con scripts para web y mobile
├── pnpm-workspace.yaml # declara `apps/*` y `packages/*`
├── tsconfig.base.json # base TS con paths `@grana/*` → source directa
└── .npmrc # hoist patterns necesarios para eslint-config-next
Reglas rápidas:
apps/<name>/.packages/<name>/.AGENTS.md → "Web ↔ Mobile policy"). No se comparte JSX entre web y React Native.Por ser monorepo, Vercel necesita saber qué subdirectorio buildear. En el dashboard del proyecto → Settings → Build & Development Settings → Root Directory, setear apps/web. Las env vars del proyecto (NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY) no cambian. Vercel detecta el pnpm-workspace.yaml en la raíz y corre pnpm install desde ahí.
Acción única por entorno: hay que cambiarlo antes del primer push post-migración para evitar un build rojo. Sin Root Directory ajustado, Vercel buildea la raíz y no encuentra Next.
SUPABASE_SETUP.md)