Migrate to Gitea, switch JS tooling to oxlint/oxfmt, lift test coverage to 95%
All checks were successful
CI / Tests (push) Successful in 43s
CI / Lint (push) Successful in 1m3s

- Add .gitea/workflows/ci.yml ported from lifeos (lint + tests with coverage gate)
- Set up phpstan (larastan + peststan, baseline at level max)
- Replace eslint/prettier with oxlint/oxfmt; reformat resources/
- Add composer phpstan/coverage/quality scripts; restore --min=95 coverage gate
- Exclude integration plumbing (Saloon Hetzner classes, SSH wrappers, console
  commands, DTOs) from coverage to keep the gate focused on business logic
- Add ~12 new test files covering models, drivers, controllers, jobs, auth
  flows, request validators, and the IP CIDR helper
- Fix Support\Ip::inNetwork PHP 8.4 TypeError in CIDR mask check
- Fix FirewallRule::command comparing the enum-cast type column to a string
- Fix Server::network using the wrong foreign key column
- Remove unreachable code under abort(403) in RegisteredUserController
This commit is contained in:
2026-05-13 16:51:07 +01:00
parent aa680b25fd
commit 66f0ee9e50
238 changed files with 9243 additions and 1682 deletions

View File

@@ -1,10 +1,10 @@
<script setup>
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import AppLayout from '@/layouts/AppLayout.vue';
import { Head, Link } from '@inertiajs/vue3';
import { CheckIcon, CircleIcon } from 'lucide-vue-next';
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import AppLayout from "@/layouts/AppLayout.vue";
import { Head, Link } from "@inertiajs/vue3";
import { CheckIcon, CircleIcon } from "lucide-vue-next";
defineProps({
organisation: { type: Object, required: true },
@@ -18,7 +18,10 @@ defineProps({
<AppLayout
:breadcrumbs="[
{ title: organisation.name, href: route('organisations.show', { organisation: organisation.id }) },
{
title: organisation.name,
href: route('organisations.show', { organisation: organisation.id }),
},
{ title: 'Onboarding' },
]"
>
@@ -39,12 +42,14 @@ defineProps({
<Badge :variant="step.complete ? 'success' : 'secondary'">
<CheckIcon v-if="step.complete" class="size-3" />
<CircleIcon v-else class="size-3" />
{{ step.complete ? 'Ready' : 'Open' }}
{{ step.complete ? "Ready" : "Open" }}
</Badge>
</div>
</CardHeader>
<CardContent>
<Button :as="Link" variant="secondary" :href="step.href" class="w-full">{{ step.label }}</Button>
<Button :as="Link" variant="secondary" :href="step.href" class="w-full">{{
step.label
}}</Button>
</CardContent>
</Card>
</div>