Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
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.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)