Skip to content

alvex/Saas_basic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

181 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Eplany vue

Ett ultimat VILT (Vue, Inertia, Laravel, Tailwind) startpaket för Laravel-applikationer.

Om projektet

Larasonic Vue är ett kraftfullt startpaket som kombinerar Laravel 11 på backend med Vue 3 och Inertia på frontend. Projektet är designat för att snabbt komma igång med moderna webbapplikationer med fokus på prestanda, säkerhet och användarupplevelse.

Teknisk stack

Backend

  • PHP 8.3
  • Laravel 11
  • Laravel Octane för förbättrad prestanda
  • Laravel Cashier för Stripe-integrering
  • Laravel Jetstream för autentisering och teamhantering
  • Laravel Sanctum för API-autentisering
  • Laravel Socialite för OAuth-integration

Frontend

  • Vue 3.5
  • Inertia.js för sömlös SPA-upplevelse utan att bygga en separat API
  • Tailwind CSS 4 för styling
  • Vite 6 för snabb utveckling och byggprocess
  • Radix UI komponenter
  • VeeValidate med Zod för formulärvalidering

Utvecklingsverktyg

  • Laravel Pint för PHP-kodformatering
  • PHPStan för statisk kodanalys
  • Pest för testning
  • ESLint för JavaScript/Vue-kodkvalitet
  • Rector för automatiska koduppgraderingar
  • Docker för containerisering

Funktioner

  • Autentisering: Stöd för både traditionell inloggning, magic links och OAuth-providers
  • Dashboard: Anpassningsbar användarportal
  • Chattfunktionalitet: Inbyggd chattlösning
  • Prenumerationshantering: Integration med Stripe för betalningar och prenumerationer
  • SEO-optimering: Inbyggt stöd för meta-taggar och SEO-optimering
  • Responsiv design: Fungerar på alla enheter

Installation

Förutsättningar

  • PHP 8.3 eller högre
  • Composer
  • Node.js (eller Bun)
  • MySQL/PostgreSQL/SQLite

Steg för installation

  1. Klona projektet

    git clone https://github.com/alvex/Eplany_vue.git
    cd Eplany_vue
  2. Installera PHP-beroenden

    composer install
  3. Kopiera .env.example till .env och konfigurera miljövariabler

    cp .env.example .env
  4. Generera applikationsnyckel

    php artisan key:generate
  5. Installera JavaScript-beroenden och bygg frontend

    bun install
    bun run build
  6. Kör migrationer och seeders

    php artisan migrate --seed

Utveckling

För att starta utvecklingsmiljön:

composer dev

Detta kommando startar:

  • Laravel-servern
  • Queue worker
  • Loggvisare
  • Vite-servern för hot-reloading

Alternativt kan du köra varje del separat:

# Laravel-server
php artisan serve

# Queue worker
php artisan queue:listen --tries=1

# Vite-server
npm run dev

Byggprocess

För att bygga projektet för produktion:

bun run build

Docker

Projektet innehåller Docker-konfiguration för enkel uppsättning:

docker-compose up -d

Miljövariabler

Viktiga miljövariabler att konfigurera i .env-filen:

  • APP_ENV: Miljö (local, production)
  • APP_URL: Applikationens URL
  • DB_CONNECTION: Databastyp
  • STRIPE_KEY & STRIPE_SECRET: För Stripe-integration
  • OAUTH_*: För OAuth-providers

Tester

Kör tester med:

composer test

Kodkvalitet

Formatera koden med:

composer format

Analysera koden med:

composer analyse

Platform Billing Invoices & Templates

What it is

Super-admin–only system for creating and managing SaaS billing invoices linked to a tenant's TenantSubscription. This is not tenant operational invoices (customers / jobs) — it is platform-level billing (e.g. manual charges, custom contracts).

Key points:

  • All invoices belong to a TenantSubscription (FK enforced).
  • tenant_id is denormalised on billing_invoices from the subscription for safety.
  • Invoice templates are global (no tenant_id).
  • PDF generation is on-demand using DomPDF (same library already used for subscription invoices).

Routes

Method URL Name Purpose
GET /admin/billing/billing-invoices admin.billing.billing-invoices.index List all platform invoices
GET /admin/billing/billing-invoices/create admin.billing.billing-invoices.create Create invoice form
POST /admin/billing/billing-invoices admin.billing.billing-invoices.store Persist new invoice
GET /admin/billing/billing-invoices/{id} admin.billing.billing-invoices.show View + HTML preview
GET /admin/billing/billing-invoices/{id}/download admin.billing.billing-invoices.download Download PDF
GET /admin/settings/invoice-templates admin.settings.invoice-templates.index List templates
GET /admin/settings/invoice-templates/create admin.settings.invoice-templates.create Create template
POST /admin/settings/invoice-templates admin.settings.invoice-templates.store Persist template
GET /admin/settings/invoice-templates/{id}/edit admin.settings.invoice-templates.edit Edit template
PUT /admin/settings/invoice-templates/{id} admin.settings.invoice-templates.update Update template
DELETE /admin/settings/invoice-templates/{id} admin.settings.invoice-templates.destroy Delete template
POST /admin/settings/invoice-templates/{id}/set-default admin.settings.invoice-templates.set-default Set as default
GET /admin/settings/invoice-templates/{id}/preview admin.settings.invoice-templates.preview Render with sample data

Placeholder syntax

Templates use a minimal Mustache-like syntax. No PHP is ever evaluated from DB content.

Variables (dot-notation for nested keys):

{{invoice.number}}       {{invoice.issue_date}}   {{invoice.due_date}}
{{invoice.status}}
{{tenant.name}}          {{tenant.id}}
{{subscription.plan_name}}
{{bill_to.name}}         {{bill_to.email}}
{{totals.subtotal}}      {{totals.tax}}            {{totals.total}}
{{company.name}}

Loop over line items:

{{#items}}
  <tr>
    <td>{{description}}</td>
    <td>{{quantity}}</td>
    <td>{{unit_price}}</td>
    <td>{{tax_rate}}</td>
    <td>{{line_total}}</td>
  </tr>
{{/items}}

Security rules

Rule Detail
No server-side PHP execution Templates are plain HTML strings. Never passed to eval() or Blade's compiler.
<script> tags stripped Removed from rendered HTML before display and before PDF generation.
Inline event handlers removed on* attributes (onclick, onload, …) stripped at render time.
javascript: URIs blocked Replaced with # in href/src/action attributes.
JS field stored only invoice_templates.js is stored for reference but never injected into preview HTML or PDF.
Preview via sandboxed iframe Admin preview is rendered inside <iframe sandbox="allow-same-origin"> — no script execution.
PDF ignores JS DomPDF renders HTML+CSS only; JS is absent from the rendered document passed to DomPDF.

Monetary amounts

All amounts are stored in cents (integer). Tax rates are stored in basis points (bps): 2500 bps = 25.00%. Totals are always computed server-side — client-submitted totals are ignored.

Invoice numbering

Platform invoices use the series BILL- (e.g. BILL-000001). The sequence is stored in invoice_number_sequences (same table as SUB- series). The BillingInvoiceSeeder seeds this sequence and the default template on first run.

DB tables

Table Purpose
invoice_templates Global invoice templates (name, html, css, js, is_default)
billing_invoices Platform billing invoices per TenantSubscription
billing_invoice_items Line items for each billing invoice

Assumptions

  1. Invoice status starts as draft. Status transitions (draft→sent→paid→void) are available via InvoiceStatusRules but no UI button is provided in v1 — can be added as a follow-up.
  2. Email delivery is not implemented for platform invoices in v1 (unlike subscription invoices which use GeneratePdfAndNotify). PDF is generated on-demand at download time.
  3. bill_to_name / bill_to_email are snapshot fields — captured at creation time. They do not update if the tenant's billing profile changes.
  4. Template JS is stored to allow teams to keep JS notes alongside the template, but it is never executed. This is clearly documented in the UI with a warning.
  5. Default template enforcement: only one template can be is_default=true. This is enforced at the application layer (DB transaction) rather than a DB partial-unique index, to keep the migration simple.
  6. PDF is generated on first download, not asynchronously. For large invoice volumes a queue-based approach (like GeneratePdfAndNotify) should be added.

About

Saas basic funtioner 2026 php + vue

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors