Compare commits

...

8 Commits

Author SHA1 Message Date
m
d38719db2f fix: add email field to UserTenant TypeScript type 2026-03-30 17:19:15 +02:00
m
b21efccfb5 fix: add MAIL_FROM env (default mgmt@msbls.de) + graceful fallback when m CLI unavailable 2026-03-30 17:10:25 +02:00
m
f51d189a3b fix: show member email instead of UUID in team management 2026-03-30 17:09:14 +02:00
m
481b299e03 test: comprehensive integration tests for all API endpoints 2026-03-30 14:43:32 +02:00
m
68d48100b9 test: comprehensive integration tests for all API endpoints
Replace the existing integration test suite with a complete test covering
every registered API route. Tests use httptest with the real router and
a real DB connection (youpc.org mgmt schema).

Endpoint groups tested:
- Health, Auth (JWT validation, expired/invalid/wrong-secret)
- Current user (GET /api/me)
- Tenants (CRUD, auto-assign)
- Cases (CRUD with search/status filters)
- Parties (CRUD)
- Deadlines (CRUD, complete, batch create)
- Appointments (CRUD)
- Notes (CRUD)
- Dashboard
- Proceeding types & deadline rules
- Deadline calculator & determination (timeline, determine)
- Reports (cases, deadlines, workload, billing)
- Templates (CRUD, render)
- Time entries (CRUD, summary)
- Invoices (CRUD, status update)
- Billing rates (list, upsert)
- Notifications (list, unread count, mark read, preferences)
- Audit log (list, filtered)
- Case assignments (assign, unassign)
- Documents (list, meta)
- AI endpoints (availability check)
- Critical path E2E (case -> deadline -> appointment -> note -> time entry -> dashboard -> complete)
2026-03-30 14:41:59 +02:00
m
40a11a4c49 feat: group proceeding types by jurisdiction (UPC/DE) + add German patent proceedings 2026-03-30 14:33:28 +02:00
m
eca0cde5e7 fix: timeline 404 + calculate endpoint fixes 2026-03-30 14:32:51 +02:00
m
cf3711b2e4 fix: update seed files to use mgmt schema after migration
The search_path was changed from kanzlai to mgmt but seed files
still referenced the old schema. Also added missing is_spawn and
spawn_label columns to mgmt.deadline_rules via direct DB migration.

Root cause of timeline 404 / calculate+determine 400: the ruleColumns
query selected is_spawn and spawn_label which didn't exist in the
mgmt.deadline_rules table, causing all deadline rule queries to fail.
2026-03-30 14:30:40 +02:00
8 changed files with 1100 additions and 233 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,7 @@ type UserTenant struct {
UserID uuid.UUID `db:"user_id" json:"user_id"`
TenantID uuid.UUID `db:"tenant_id" json:"tenant_id"`
Role string `db:"role" json:"role"`
Email string `db:"email" json:"email"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log/slog"
"os"
"os/exec"
"strings"
"sync"
@@ -458,17 +459,25 @@ type UpdatePreferencesInput struct {
}
// SendEmail sends an email using the `m mail send` CLI command.
// In Docker, this will fail gracefully (m CLI not available).
// TODO: Replace with direct SMTP for production.
func SendEmail(to, subject, body string) error {
from := os.Getenv("MAIL_FROM")
if from == "" {
from = "mgmt@msbls.de"
}
cmd := exec.Command("m", "mail", "send",
"--from", from,
"--to", to,
"--subject", subject,
"--body", body,
"--yes")
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("m mail send failed: %w (output: %s)", err, string(output))
slog.Warn("email send failed (m CLI may not be available in Docker)", "to", to, "error", err, "output", string(output))
return fmt.Errorf("m mail send failed: %w", err)
}
slog.Info("email sent", "to", to, "subject", subject)
slog.Info("email sent", "from", from, "to", to, "subject", subject)
return nil
}

View File

@@ -139,7 +139,11 @@ func (s *TenantService) FirstTenantForUser(ctx context.Context, userID uuid.UUID
func (s *TenantService) ListMembers(ctx context.Context, tenantID uuid.UUID) ([]models.UserTenant, error) {
var members []models.UserTenant
err := s.db.SelectContext(ctx, &members,
`SELECT user_id, tenant_id, role, created_at FROM user_tenants WHERE tenant_id = $1 ORDER BY created_at`,
`SELECT ut.user_id, ut.tenant_id, ut.role, ut.created_at, COALESCE(au.email, '') as email
FROM user_tenants ut
LEFT JOIN auth.users au ON au.id = ut.user_id
WHERE ut.tenant_id = $1
ORDER BY ut.created_at`,
tenantID,
)
if err != nil {

View File

@@ -2,7 +2,7 @@
-- Creates 1 test tenant, 5 cases with deadlines and appointments
-- Run with: psql $DATABASE_URL -f demo_data.sql
SET search_path TO kanzlai, public;
SET search_path TO mgmt, public;
-- Demo tenant
INSERT INTO tenants (id, name, slug, settings) VALUES

View File

@@ -1,6 +1,6 @@
-- UPC Proceeding Timeline: Full event tree with conditional deadlines
-- Ported from youpc.org migrations 039 + 040
-- Run against kanzlai schema in flexsiebels Supabase instance
-- Run against mgmt schema in youpc.org Supabase instance
-- ========================================
-- 1. Add is_spawn + spawn_label columns

View File

@@ -164,7 +164,7 @@ export function TeamSettings() {
</div>
<div>
<p className="text-sm font-medium text-neutral-900">
{member.user_id.slice(0, 8)}...
{member.email || member.user_id.slice(0, 8) + "..."}
</p>
<p className="text-xs text-neutral-500">{roleInfo.label}</p>
</div>

View File

@@ -15,6 +15,7 @@ export interface UserTenant {
user_id: string;
tenant_id: string;
role: string;
email: string;
created_at: string;
}