feat(starter): intial starter release
This commit is contained in:
18
.gitignore
vendored
18
.gitignore
vendored
@@ -1,3 +1,10 @@
|
||||
# lst ignores
|
||||
docker-compose.yml
|
||||
frontend/.tanstack/
|
||||
frontend/.output/
|
||||
frontend/.nitro/
|
||||
scripts/releases
|
||||
|
||||
# ---> Go
|
||||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
@@ -25,16 +32,6 @@ go.work.sum
|
||||
# env file
|
||||
.env
|
||||
|
||||
# ---> Go.AllowList
|
||||
# Allowlisting gitignore template for GO projects prevents us
|
||||
# from adding various unwanted local files, such as generated
|
||||
# files, developer configurations or IDE-specific files etc.
|
||||
#
|
||||
# Recommended: Go.AllowList.gitignore
|
||||
|
||||
# Ignore everything
|
||||
*
|
||||
|
||||
# But not these files...
|
||||
!/.gitignore
|
||||
|
||||
@@ -198,3 +195,4 @@ dist
|
||||
*.resources
|
||||
test-results/
|
||||
|
||||
backend/go.sum
|
||||
|
||||
17
.versionrc.json
Normal file
17
.versionrc.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"types": [
|
||||
{ "type": "feat", "section": "🌟 Enhancements" },
|
||||
{ "type": "fix", "section": "🐛 Bug fixes" },
|
||||
{ "type": "chore", "hidden": false, "section": "📝 Chore" },
|
||||
{ "type": "docs", "section": "📚 Documentation" },
|
||||
{ "type": "style", "hidden": true },
|
||||
{ "type": "refactor", "section": "🛠️ Code Refactor" },
|
||||
{ "type": "perf", "hidden": false, "section": "🚀 Performance" },
|
||||
{ "type": "test", "section": "📝 Testing Code" },
|
||||
{ "type": "ci", "hidden": true, "section": "📈 Project changes" },
|
||||
{ "type": "build", "hidden": true, "section": "📈 Project Builds" }
|
||||
],
|
||||
"commitUrlFormat": "https://git.tuffraid.net/cowch/logistics_support_tool/commits/{{hash}}",
|
||||
"compareUrlFormat": "https://git.tuffraid.net/cowch/logistics_support_tool/compare/{{previousTag}}...{{currentTag}}",
|
||||
"header": "# All changes to lst are shown below.\n"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# logistics_support_tool
|
||||
|
||||
This is the new logisitcs support tool
|
||||
This is the new logisitcs support tool
|
||||
|
||||
backend written in go
|
||||
front end written in vite/react
|
||||
@@ -9,4 +9,4 @@ db postgress.
|
||||
this will also include a primary server to house all the common configs across all servers to keep it more easy to admin. the servers will cache this data and check for changes every hour
|
||||
|
||||
The new lst will run in docker by building your own image and deploying or pulling the image down.
|
||||
you will also be able to run it in windows or linux.
|
||||
you will also be able to run it in windows or linux.
|
||||
|
||||
35
backend/Dockerfile
Normal file
35
backend/Dockerfile
Normal file
@@ -0,0 +1,35 @@
|
||||
FROM golang:1.24.4-alpine3.22 AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
# COPY VERSION ./VERSION
|
||||
|
||||
RUN go mod download
|
||||
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -o lst_go ./main.go
|
||||
|
||||
FROM alpine:latest
|
||||
|
||||
WORKDIR /root/
|
||||
|
||||
COPY --from=builder /app/lst_go .
|
||||
# COPY --from=builder /app/VERSION ./
|
||||
|
||||
# create the volume paths
|
||||
RUN mkdir -p /data
|
||||
VOLUME /data
|
||||
|
||||
# this port is hardcoded in the app right now.
|
||||
EXPOSE 8080
|
||||
ENV RUNNING_IN_DOCKER=true
|
||||
|
||||
# VOLUME /data
|
||||
# ENV DB_TYPE=sqlite
|
||||
# ENV DB_PATH=/data/lst_go.db
|
||||
# ENV POSTGRES_HOST=host
|
||||
# ENV POSTGRES_USER=user
|
||||
# ENV POSTGRES_PASSWORD=pass
|
||||
|
||||
CMD ["./lst_go"]
|
||||
34
backend/go.mod
Normal file
34
backend/go.mod
Normal file
@@ -0,0 +1,34 @@
|
||||
module lst.net
|
||||
|
||||
go 1.24.3
|
||||
|
||||
require github.com/gin-gonic/gin v1.10.1
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
20
backend/main.go
Normal file
20
backend/main.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("Welcome to lst backend where all the fun happens.")
|
||||
r := gin.Default()
|
||||
|
||||
r.GET("/", errorLoc)
|
||||
r.Run(":8080")
|
||||
}
|
||||
|
||||
func errorLoc(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"message": "welcome to lst system you might have just encountered an incorrect area of the app"})
|
||||
}
|
||||
21
docker-compose-example.yml
Normal file
21
docker-compose-example.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
services:
|
||||
lst_backend:
|
||||
# build: . # Tell Docker Compose to build the image using the Dockerfile in the current directory
|
||||
image: git.tuffraid.net/cowch/logistics_support_tool:backend-latest
|
||||
container_name: lst_backend # A friendly name for your running container
|
||||
volumes:
|
||||
- /path/to/frontend/backend:/data
|
||||
ports:
|
||||
- "8080:8080"
|
||||
restart: unless-stopped
|
||||
|
||||
lst_frontend:
|
||||
# build: . # Tell Docker Compose to build the image using the Dockerfile in the current directory
|
||||
image: git.tuffraid.net/cowch/logistics_support_tool:frontend-latest
|
||||
container_name: lst_frontend # A friendly name for your running container
|
||||
volumes:
|
||||
- /path/to/frontend/data:/data
|
||||
ports:
|
||||
- "3120:3000"
|
||||
restart: unless-stopped
|
||||
29
frontend/Dockerfile
Normal file
29
frontend/Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
||||
# Build Stage
|
||||
FROM node:24-alpine AS deps
|
||||
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
# Build the Next.js app
|
||||
FROM node:24-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY . ./
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
# Run other commands like prisma or drizzle
|
||||
RUN npm run build
|
||||
|
||||
# if more commands are needed after here do the same
|
||||
|
||||
# Final stage
|
||||
FROM node:24-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/.nitro /app/.nitro
|
||||
COPY --from=builder /app/.output /app/.output
|
||||
COPY --from=builder /app/.tanstack /app/.tanstack
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["node", ".output/server/index.mjs"]
|
||||
10170
frontend/package-lock.json
generated
Normal file
10170
frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
frontend/package.json
Normal file
27
frontend/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@tanstack/react-router": "^1.127.3",
|
||||
"@tanstack/react-start": "^1.127.4",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"vite": "^7.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"typescript": "^5.8.3",
|
||||
"vite-tsconfig-paths": "^5.1.4"
|
||||
}
|
||||
}
|
||||
59
frontend/src/routeTree.gen.ts
Normal file
59
frontend/src/routeTree.gen.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/* eslint-disable */
|
||||
|
||||
// @ts-nocheck
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
|
||||
// This file was automatically generated by TanStack Router.
|
||||
// You should NOT make any changes in this file as it will be overwritten.
|
||||
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
||||
|
||||
import { Route as rootRouteImport } from './routes/__root'
|
||||
import { Route as IndexRouteImport } from './routes/index'
|
||||
|
||||
const IndexRoute = IndexRouteImport.update({
|
||||
id: '/',
|
||||
path: '/',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
|
||||
export interface FileRoutesByFullPath {
|
||||
'/': typeof IndexRoute
|
||||
}
|
||||
export interface FileRoutesByTo {
|
||||
'/': typeof IndexRoute
|
||||
}
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRouteImport
|
||||
'/': typeof IndexRoute
|
||||
}
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
fullPaths: '/'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to: '/'
|
||||
id: '__root__' | '/'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
export interface RootRouteChildren {
|
||||
IndexRoute: typeof IndexRoute
|
||||
}
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface FileRoutesByPath {
|
||||
'/': {
|
||||
id: '/'
|
||||
path: '/'
|
||||
fullPath: '/'
|
||||
preLoaderRoute: typeof IndexRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rootRouteChildren: RootRouteChildren = {
|
||||
IndexRoute: IndexRoute,
|
||||
}
|
||||
export const routeTree = rootRouteImport
|
||||
._addFileChildren(rootRouteChildren)
|
||||
._addFileTypes<FileRouteTypes>()
|
||||
19
frontend/src/router.tsx
Normal file
19
frontend/src/router.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
// src/router.tsx
|
||||
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
|
||||
import { routeTree } from './routeTree.gen'
|
||||
|
||||
export function createRouter() {
|
||||
const router = createTanStackRouter({
|
||||
basepath: '/lst',
|
||||
routeTree,
|
||||
scrollRestoration: true,
|
||||
})
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface Register {
|
||||
router: ReturnType<typeof createRouter>
|
||||
}
|
||||
}
|
||||
48
frontend/src/routes/__root.tsx
Normal file
48
frontend/src/routes/__root.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
/// <reference types="vite/client" />
|
||||
import type { ReactNode } from 'react'
|
||||
import {
|
||||
Outlet,
|
||||
createRootRoute,
|
||||
HeadContent,
|
||||
Scripts,
|
||||
} from '@tanstack/react-router'
|
||||
|
||||
export const Route = createRootRoute({
|
||||
head: () => ({
|
||||
meta: [
|
||||
{
|
||||
charSet: 'utf-8',
|
||||
},
|
||||
{
|
||||
name: 'viewport',
|
||||
content: 'width=device-width, initial-scale=1',
|
||||
},
|
||||
{
|
||||
title: 'TanStack Start Starter',
|
||||
},
|
||||
],
|
||||
}),
|
||||
component: RootComponent,
|
||||
})
|
||||
|
||||
function RootComponent() {
|
||||
return (
|
||||
<RootDocument>
|
||||
<Outlet />
|
||||
</RootDocument>
|
||||
)
|
||||
}
|
||||
|
||||
function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
|
||||
return (
|
||||
<html>
|
||||
<head>
|
||||
<HeadContent />
|
||||
</head>
|
||||
<body>
|
||||
{children}
|
||||
<Scripts />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
48
frontend/src/routes/index.tsx
Normal file
48
frontend/src/routes/index.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
// src/routes/index.tsx
|
||||
import * as fs from 'node:fs'
|
||||
import { createFileRoute, useRouter } from '@tanstack/react-router'
|
||||
import { createServerFn } from '@tanstack/react-start'
|
||||
|
||||
const filePath = 'count.txt'
|
||||
|
||||
async function readCount() {
|
||||
return parseInt(
|
||||
await fs.promises.readFile(filePath, 'utf-8').catch(() => '0'),
|
||||
)
|
||||
}
|
||||
|
||||
const getCount = createServerFn({
|
||||
method: 'GET',
|
||||
}).handler(() => {
|
||||
return readCount()
|
||||
})
|
||||
|
||||
const updateCount = createServerFn({ method: 'POST' })
|
||||
.validator((d: number) => d)
|
||||
.handler(async ({ data }) => {
|
||||
const count = await readCount()
|
||||
await fs.promises.writeFile(filePath, `${count + data}`)
|
||||
})
|
||||
|
||||
export const Route = createFileRoute('/')({
|
||||
component: Home,
|
||||
loader: async () => await getCount(),
|
||||
})
|
||||
|
||||
function Home() {
|
||||
const router = useRouter()
|
||||
const state = Route.useLoaderData()
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
updateCount({ data: 1 }).then(() => {
|
||||
router.invalidate()
|
||||
})
|
||||
}}
|
||||
>
|
||||
Add 1 to {state}?
|
||||
</button>
|
||||
)
|
||||
}
|
||||
10
frontend/tsconfig.json
Normal file
10
frontend/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"moduleResolution": "Bundler",
|
||||
"module": "ESNext",
|
||||
"target": "ES2022",
|
||||
"skipLibCheck": true,
|
||||
"strictNullChecks": true
|
||||
}
|
||||
}
|
||||
11
frontend/vite.config.ts
Normal file
11
frontend/vite.config.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import tsConfigPaths from 'vite-tsconfig-paths'
|
||||
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
|
||||
|
||||
export default defineConfig({
|
||||
base: '/lst/',
|
||||
server: {
|
||||
port: 3000,
|
||||
},
|
||||
plugins: [tsConfigPaths(), tanstackStart({ target: 'node-server' })],
|
||||
})
|
||||
3905
package-lock.json
generated
Normal file
3905
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
31
package.json
Normal file
31
package.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "logistics_support_tool",
|
||||
"version": "1.0.0",
|
||||
"description": "This is the new logisitcs support tool",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"backend": "cd backend && go run .",
|
||||
"docker:front":"docker build -t logistics_support_tool:frontend-latest -f frontend/Dockerfile ./frontend",
|
||||
"docker:back":"docker build -t logistics_support_tool:backend-latest -f backend/Dockerfile ./backend",
|
||||
"docker": "powershell -File ./scripts/dockerBuild.ps1",
|
||||
"release":"powershell -File ./scripts/release.ps1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.tuffraid.net/cowch/logistics_support_tool.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"standard-version": "^9.5.0"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
}
|
||||
}
|
||||
}
|
||||
15
scripts/dockerBuild.ps1
Normal file
15
scripts/dockerBuild.ps1
Normal file
@@ -0,0 +1,15 @@
|
||||
Write-Host "Building the docker images for front and backend"
|
||||
docker build -t logistics_support_tool:frontend-latest -f ../frontend/Dockerfile ../frontend
|
||||
docker build -t logistics_support_tool:backend-latest -f ../backend/Dockerfile ../backend
|
||||
|
||||
Write-Host "Tagging the builds with latest this is for testing test basically."
|
||||
docker tag logistics_support_tool:frontend-latest git.tuffraid.net/cowch/logistics_support_tool:frontend-latest
|
||||
docker tag logistics_support_tool:backend-latest git.tuffraid.net/cowch/logistics_support_tool:backend-latest
|
||||
|
||||
# docker build -t logistics_support_tool:frontend-latest --no-cache .
|
||||
Write-Host "Push both builds to our gitea server."
|
||||
docker push git.tuffraid.net/cowch/logistics_support_tool:frontend-latest
|
||||
docker push git.tuffraid.net/cowch/logistics_support_tool:backend-latest
|
||||
|
||||
Write-Host "Pull the new images to our docker system"
|
||||
docker compose -f ./docker-compose.yml up -d --force-recreate
|
||||
68
scripts/release.ps1
Normal file
68
scripts/release.ps1
Normal file
@@ -0,0 +1,68 @@
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$versionFile = Join-Path $scriptDir "..\VERSION"
|
||||
$env:GOOS = "windows"
|
||||
$env:GOARCH = "amd64"
|
||||
$keepReleases = 10
|
||||
|
||||
if (Test-Path $versionFile) {
|
||||
$version = Get-Content $versionFile -Raw | ForEach-Object { $_.Trim() }
|
||||
Write-Host "Project version: $version"
|
||||
} else {
|
||||
Write-Host "VERSION file not found at $versionFile"
|
||||
}
|
||||
|
||||
Write-Host "Building release version: $version"
|
||||
|
||||
Write-Host "`nBuilding Go backend..."
|
||||
Push-Location ./backend
|
||||
|
||||
go build -ldflags "-X main.version=$version" -o lst_backend.exe ./main.go
|
||||
Pop-Location
|
||||
|
||||
Write-Host "`nBuilding frontend..."
|
||||
Push-Location ./frontend
|
||||
npm install
|
||||
npm run build
|
||||
Pop-Location
|
||||
|
||||
|
||||
$releaseFolder = Join-Path $scriptDir "releases"
|
||||
$zipName = "release-$version.zip"
|
||||
$zipPath = Join-Path $releaseFolder $zipName
|
||||
|
||||
|
||||
if (-not (Test-Path $releaseFolder)) {
|
||||
New-Item -ItemType Directory -Path $releaseFolder | Out-Null
|
||||
}
|
||||
|
||||
# Remove zip if it already exists
|
||||
if (Test-Path $zipPath) {
|
||||
Write-Host "Removing existing zip: $zipPath"
|
||||
Remove-Item $zipPath -Force
|
||||
}
|
||||
|
||||
# Clean up older release files (keep only newest X)
|
||||
$existingZips = Get-ChildItem -Path $releaseFolder -Filter "release-*.zip" | Sort-Object LastWriteTime -Descending
|
||||
|
||||
if ($existingZips.Count -gt $keepReleases) {
|
||||
$toRemove = $existingZips | Select-Object -Skip $keepReleases
|
||||
foreach ($file in $toRemove) {
|
||||
Write-Host "Deleting old release: $($file.Name)"
|
||||
Remove-Item $file.FullName -Force
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`nPackaging release: $($zipName)"
|
||||
|
||||
$filesToInclude = @(
|
||||
"backend\lst_backend.exe",
|
||||
"frontend\.nitro",
|
||||
"frontend\.tanstack",
|
||||
"frontend\.output",
|
||||
"frontend\public",
|
||||
"VERSION"
|
||||
)
|
||||
|
||||
Compress-Archive -Path $filesToInclude -DestinationPath $zipPath
|
||||
|
||||
Write-Host "`nRelease package created at: $($zipPath)"
|
||||
Reference in New Issue
Block a user