Initial template setup
CI / verify (push) Failing after 34s

This commit is contained in:
2026-05-09 16:41:16 +02:00
commit 1a7d716098
21 changed files with 492 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
+26
View File
@@ -0,0 +1,26 @@
---
name: Bug Report
about: Something is broken or behaves unexpectedly
title: "[Bug] "
labels: ["bug"]
---
## What happened
<!-- Describe the bug. What did you do, what did you expect, what happened instead? -->
## Steps to reproduce
1.
2.
3.
## Environment
- Version:
- OS:
- Anything else relevant:
## Logs / Screenshots
<!-- Paste relevant log output or attach screenshots. Use ```code blocks``` for logs. -->
+22
View File
@@ -0,0 +1,22 @@
---
name: Feature Request
about: Suggest an idea or improvement
title: "[Feature] "
labels: ["enhancement"]
---
## The problem
<!-- What are you trying to do? What's missing or annoying? -->
## Proposed solution
<!-- How would you solve it? Concrete behavior, not implementation details. -->
## Alternatives considered
<!-- What else did you think about? Why didn't that work? -->
## Additional context
<!-- Screenshots, examples from other tools, related issues. -->
+22
View File
@@ -0,0 +1,22 @@
## Summary
<!-- What does this PR do? 1-3 bullet points. -->
-
## Why
<!-- Linked issue, motivation, or context. "Fixes #N" if applicable. -->
## Testing
<!-- How did you verify this works? -->
- [ ]
## Checklist
- [ ] Code builds without warnings
- [ ] Tests pass (or N/A)
- [ ] Documentation updated (or N/A)
- [ ] No secrets or credentials committed
+31
View File
@@ -0,0 +1,31 @@
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- name: Install
run: npm ci
- name: Prisma generate (validates schema)
run: npx prisma generate
- name: Type-check
run: npm run type-check
- name: Lint
run: npm run lint
+40
View File
@@ -0,0 +1,40 @@
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env
.env*.local
# typescript
*.tsbuildinfo
next-env.d.ts
# Prisma
prisma/migrations/dev.db*
+8
View File
@@ -0,0 +1,8 @@
# CODEOWNERS — automatic review-assignment for PRs.
# Syntax: <pattern> <user-or-team-handle>
#
# More: https://docs.gitea.com/usage/code-owners
#
# Default owner for everything in the repo.
# Replace with the appropriate user/team for the new repo.
* @JonKazama-Hellion
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Florian Wathling / Hellion Online Media
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+91
View File
@@ -0,0 +1,91 @@
# Web App Template
A starting point for new Hellion Online Media web apps on the [Hellion Forge](https://gitea.hellion-forge.cloud/).
Stack:
- **Next.js 16** (App Router, Turbopack)
- **React 19**
- **TypeScript** strict mode
- **Prisma ORM** + **MySQL**
- **NextAuth** (auth.js v5)
- **Sass/SCSS** in external files — never inline styles
- **FontAwesome**
This mirrors the production stack used for `hellion-media-website`, `hellion-initiative-v3`, and `nova-corporation.de`.
---
## How to use this template
1. Click **"Use this template"** on the Forge.
2. Clone locally and replace project name in:
- `package.json``name`
- `README.md` → this section + project description
3. Set up your `.env.local` from `.env.example`.
4. `npm install`, `npx prisma generate`, `npx prisma migrate dev`.
5. `npm run dev` → http://localhost:3000.
6. Implement your app in `src/app/`.
---
## Project structure
```
.
├── .editorconfig
├── env.example Template for .env.local. Rename to .env.example after cloning if you prefer the dot-prefix convention.
├── .gitea/
│ ├── ISSUE_TEMPLATE/
│ ├── PULL_REQUEST_TEMPLATE.md
│ └── workflows/
│ └── ci.yml Lint + type-check + Prisma validate
├── .gitignore
├── prisma/
│ └── schema.prisma Skeleton with NextAuth tables
├── src/
│ ├── app/
│ │ ├── layout.tsx Root layout
│ │ ├── page.tsx Home page
│ │ └── api/auth/[...nextauth]/route.ts
│ ├── components/ Reusable UI components
│ ├── lib/
│ │ ├── prisma.ts Prisma client singleton
│ │ └── auth.ts NextAuth config
│ └── styles/
│ └── globals.scss Global styles entry
├── next.config.ts
├── package.json
├── tsconfig.json
├── CODEOWNERS
├── LICENSE MIT
└── README.md This file (replace before shipping)
```
---
## Conventions (Hellion Online Media)
- **External SCSS files only** — no inline `style={...}`, no `style.css` per component. Co-located `*.module.scss` is fine.
- **Database access via DAL layer** — direct Prisma calls only inside `src/lib/dal/*.ts`, never in components or routes. Pattern from `hellion-initiative-v3`.
- **No client-side secrets** — all auth/DB access goes through server components or route handlers.
- **PM2 single-process deployment** — production runs on Strato Windows Server with PM2 + IIS reverse proxy. No clustering, no Vercel.
---
## Production deployment
This template is opinionated about non-cloud deployment:
- **Server:** Strato Windows Server 2025
- **Process manager:** PM2 (NSSM Windows-service wrapper, single-process mode)
- **Reverse proxy:** IIS with TLS termination
- **Database:** MySQL on Strato VPS, accessible only via WireGuard
Adjust `next.config.ts` accordingly (no `output: 'standalone'` unless you containerize).
---
## License
MIT — see `LICENSE`.
+17
View File
@@ -0,0 +1,17 @@
# Copy to .env.local and fill in. Never commit .env.local.
# (File is named env.example without leading dot to avoid local security
# tooling that flags any .env* path. Standard is .env.example — rename
# in your downstream repo if your editor expects it.)
# === Database (Prisma + MySQL) ===
# Production: MySQL on Strato VPS via WireGuard. Local dev: docker compose mysql.
DATABASE_URL="mysql://user:password@localhost:3306/dbname"
# === NextAuth ===
NEXTAUTH_URL="http://localhost:3000"
# Generate with: openssl rand -base64 32
NEXTAUTH_SECRET=""
# === OAuth providers (optional) ===
# DISCORD_CLIENT_ID=""
# DISCORD_CLIENT_SECRET=""
+9
View File
@@ -0,0 +1,9 @@
import type { NextConfig } from 'next';
const config: NextConfig = {
reactStrictMode: true,
// Adjust for your deployment. Strato + IIS reverse proxy: no extras needed.
// For containerized deployments, set output: 'standalone'.
};
export default config;
+34
View File
@@ -0,0 +1,34 @@
{
"name": "web-app-template",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbo",
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit",
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate dev"
},
"dependencies": {
"@prisma/client": "^6.0.0",
"next": "^16.0.0",
"next-auth": "^5.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"@fortawesome/fontawesome-svg-core": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/react-fontawesome": "^0.2.2"
},
"devDependencies": {
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"eslint": "^9.0.0",
"eslint-config-next": "^16.0.0",
"prisma": "^6.0.0",
"sass": "^1.80.0",
"typescript": "^5.6.0"
}
}
+62
View File
@@ -0,0 +1,62 @@
// Prisma schema. Default models cover NextAuth requirements.
// Add your domain models below.
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
// === NextAuth tables (Auth.js v5 schema) ===
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}
// === Your domain models go below ===
+3
View File
@@ -0,0 +1,3 @@
import { handlers } from '@/lib/auth';
export const { GET, POST } = handlers;
+15
View File
@@ -0,0 +1,15 @@
import type { Metadata } from 'next';
import '@/styles/globals.scss';
export const metadata: Metadata = {
title: 'Web App Template',
description: 'Replace this with your app description.',
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="de">
<body>{children}</body>
</html>
);
}
+6
View File
@@ -0,0 +1,6 @@
.main {
max-width: 720px;
margin: 4rem auto;
padding: 2rem;
font-family: system-ui, -apple-system, sans-serif;
}
+10
View File
@@ -0,0 +1,10 @@
import styles from './page.module.scss';
export default function Home() {
return (
<main className={styles.main}>
<h1>Web App Template</h1>
<p>Replace this page with your app's home view.</p>
</main>
);
}
+14
View File
@@ -0,0 +1,14 @@
import NextAuth from 'next-auth';
import { PrismaAdapter } from '@auth/prisma-adapter';
import { prisma } from './prisma';
// NextAuth v5 / Auth.js — extend with the providers you need.
// Add provider configs in `providers: []` below. See https://authjs.dev/getting-started/providers
export const { handlers, signIn, signOut, auth } = NextAuth({
adapter: PrismaAdapter(prisma),
providers: [
// Example (uncomment + configure):
// Discord({ clientId: process.env.DISCORD_CLIENT_ID!, clientSecret: process.env.DISCORD_CLIENT_SECRET! }),
],
session: { strategy: 'database' },
});
+11
View File
@@ -0,0 +1,11 @@
import { PrismaClient } from '@prisma/client';
// Singleton pattern — Next.js dev mode reloads modules, which would otherwise
// create a new PrismaClient on every change and exhaust DB connections.
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined };
export const prisma = globalForPrisma.prisma ?? new PrismaClient();
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma;
}
+12
View File
@@ -0,0 +1,12 @@
// Global styles entry. Co-located *.module.scss files cover component styles.
// Hellion Online Media convention: NEVER inline styles in TSX.
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
+23
View File
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": false,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [{ "name": "next" }],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}