feat: setup monorepo infra — Go API + Vue 3 + PostgreSQL + Dockerfile Dokploy

Monorepo com apps/api (Go 1.23 + chi + pgx) e apps/web (Vue 3 + Vite + TypeScript).
Dockerfile multi-stage consolida tudo em imagem única (~25MB) para deploy no Dokploy.
Migrations rodando na inicialização; Vue embedado no binário Go via //go:embed.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
2026-05-26 20:06:37 -03:00
co-authored by Claude Sonnet 4.6
commit a3d8f363a5
25 changed files with 2131 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Financeiro Carvalho</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
+1610
View File
File diff suppressed because it is too large Load Diff
+22
View File
@@ -0,0 +1,22 @@
{
"name": "financeiro-carvalho-web",
"version": "0.0.1",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"pinia": "^2.3.1",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.1",
"typescript": "^5.7.2",
"vite": "^6.3.5",
"vue-tsc": "^2.2.8"
}
}
+3
View File
@@ -0,0 +1,3 @@
<template>
<RouterView />
</template>
+10
View File
@@ -0,0 +1,10 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')
+15
View File
@@ -0,0 +1,15 @@
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView,
},
],
})
export default router
+6
View File
@@ -0,0 +1,6 @@
<template>
<main style="font-family: sans-serif; padding: 2rem; text-align: center">
<h1>Financeiro Carvalho</h1>
<p>Sistema de controle financeiro pessoal</p>
</main>
</template>
+22
View File
@@ -0,0 +1,22 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"moduleResolution": "Bundler",
"strict": true,
"noEmit": true,
"jsx": "preserve",
"jsxImportSource": "vue",
"resolveJsonModule": true,
"isolatedModules": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*", "src/**/*.vue"],
"exclude": ["node_modules"]
}
+7
View File
@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.node.json" },
{ "path": "./tsconfig.app.json" }
]
}
+12
View File
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noEmit": true
},
"include": ["vite.config.ts"]
}
+20
View File
@@ -0,0 +1,20 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
},
},
},
})