feat(navigation): add prominent validation quickstart action

This commit is contained in:
Schubert Ferenc 2026-07-11 18:02:53 +02:00
parent 0bbcaba211
commit 9c6b184e39
28614 changed files with 4356173 additions and 23 deletions

View file

@ -53,12 +53,16 @@ from app.schemas.domain import (
ValidationRead,
ValidationReview,
ValidationUpdate,
QuickStartCreateRequest,
QuickStartCustomerData,
QuickStartValidationSummary,
UserCreate,
UserRead,
UserUpdate,
UserPasswordResetRequest,
)
from app.services.domain_service import CrudService, DomainServices
from app.services.quickstart_service import QuickStartService
from app.services.validation_workflow import ValidationWorkflowService
router = APIRouter(tags=["domain"], dependencies=[Depends(current_user)])
@ -204,6 +208,14 @@ def delete_customer(item_id: str, session: Session = Depends(get_session)):
return commit_delete(session, DomainServices(session).customers, item_id)
@router.get("/customers/{item_id}/quickstart-data", response_model=QuickStartCustomerData)
def customer_quickstart_data(item_id: str, session: Session = Depends(get_session)):
try:
return QuickStartService(session).customer_data(item_id)
except ValueError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
@router.get("/locations", response_model=PaginatedResponse[LocationRead])
def list_locations(params: dict = Depends(paging), session: Session = Depends(get_session)):
return DomainServices(session).locations.list(**params)
@ -338,11 +350,35 @@ def get_validation(item_id: str, session: Session = Depends(get_session)):
return item
@router.get("/devices/{item_id}/last-validation", response_model=QuickStartValidationSummary | None)
def last_device_validation(item_id: str, session: Session = Depends(get_session)):
try:
return QuickStartService(session).device_last_validation(item_id)
except ValueError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
@router.post("/validations", response_model=ValidationRead, status_code=201)
def create_validation(payload: ValidationCreate, session: Session = Depends(get_session)):
return commit_create(session, DomainServices(session).validations, payload)
@router.post("/validations/quick-start", response_model=ValidationRead, status_code=201)
def create_quick_start_validation(
payload: QuickStartCreateRequest,
session: Session = Depends(get_session),
me: User = Depends(current_user),
):
try:
validation = QuickStartService(session).create_validation(payload, me)
session.commit()
session.refresh(validation)
return validation
except ValueError as exc:
session.rollback()
raise HTTPException(status_code=422, detail=str(exc)) from exc
@router.put("/validations/{item_id}", response_model=ValidationRead)
def update_validation(
item_id: str, payload: ValidationUpdate, session: Session = Depends(get_session)

View file

@ -8,6 +8,7 @@ from pathlib import Path
from app.db.session import SessionLocal
from app.models.user import User
from app.services.demo_data import DemoDataService
from app.services.reference_masterdata import ReferenceMasterdataImportService
@ -83,6 +84,20 @@ def cmd_create_admin(_: argparse.Namespace) -> int:
return 0
def cmd_demo_data(args: argparse.Namespace) -> int:
with SessionLocal() as session:
summary = DemoDataService(session).run(
customers=args.customers,
devices=args.devices,
validations=args.validations,
reports=args.reports,
images=args.images,
reset=args.reset,
)
print(json.dumps(summary, ensure_ascii=False))
return 0
def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(prog="python -m app.cli")
subparsers = parser.add_subparsers(dest="command", required=True)
@ -101,6 +116,15 @@ def build_parser() -> argparse.ArgumentParser:
admin_parser = subparsers.add_parser("create-admin")
admin_parser.set_defaults(func=cmd_create_admin)
demo_parser = subparsers.add_parser("demo-data")
demo_parser.add_argument("--customers", type=int, default=10)
demo_parser.add_argument("--devices", type=int, default=10)
demo_parser.add_argument("--validations", type=int, default=20)
demo_parser.add_argument("--reports", action="store_true")
demo_parser.add_argument("--images", action="store_true")
demo_parser.add_argument("--reset", action="store_true")
demo_parser.set_defaults(func=cmd_demo_data)
return parser

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from sqlalchemy import select
from sqlalchemy import or_, select
from sqlalchemy.orm import Session
from app.models.customer import Customer
@ -23,7 +23,22 @@ class UserRepository(Repository[User]):
class CustomerRepository(Repository[Customer]):
model = Customer
search_columns = ("name", "city", "email", "phone")
def _search_statement(self, search: str | None = None):
statement = select(Customer)
if search:
term = f"%{search.strip()}%"
statement = statement.where(
or_(
Customer.name.ilike(term),
Customer.city.ilike(term),
Customer.postal_code.ilike(term),
Customer.email.ilike(term),
Customer.phone.ilike(term),
Customer.contacts.any(Contact.full_name.ilike(term)),
)
)
return statement
class LocationRepository(Repository[Location]):

View file

@ -269,3 +269,31 @@ class UserRead(UserBase, EntityRead):
class UserPasswordResetRequest(ORMModel):
temporary_password: str | None = None
class QuickStartValidationSummary(ORMModel):
id: str
device_id: str
report_number: str
performed_on: date | None = None
result: str | None = None
next_validation_on: date | None = None
status: str
validation_type: str | None = None
equipment_ids: list[str] = Field(default_factory=list)
class QuickStartCustomerData(ORMModel):
customer: CustomerRead
locations: list[LocationRead] = Field(default_factory=list)
contacts: list[ContactRead] = Field(default_factory=list)
devices: list[DeviceRead] = Field(default_factory=list)
validations: list[QuickStartValidationSummary] = Field(default_factory=list)
class QuickStartCreateRequest(ORMModel):
customer_id: UUID
location_id: UUID | None = None
contact_id: UUID | None = None
device_id: UUID | None = None
validation_type: str

View file

@ -0,0 +1,757 @@
from __future__ import annotations
from copy import deepcopy
from dataclasses import dataclass
from datetime import date
from pathlib import Path
import shutil
from typing import Any
from dateutil.relativedelta import relativedelta
from sqlalchemy import delete, select
from sqlalchemy.orm import Session
from app.models.contact import Contact
from app.models.customer import Customer, CustomerType
from app.models.device import Device
from app.models.equipment import Equipment, EquipmentKind, EquipmentStatus
from app.models.location import Location
from app.models.validation import Validation, ValidationStatus
from app.modules.orion.service import OrionReportService
from app.modules.orion.template_service import ReportTemplateService
from app.services.validation_workflow import ValidationWorkflowService
DEMO_TAG = "DEMO_DATA"
DEMO_REPORT_PREFIX = "DEMO-VAL"
DEMO_DEVICE_PREFIX = "DEMO-DEV"
DEMO_EQUIPMENT_PREFIX = "DEMO-EQ"
DEMO_UPLOAD_ROOT = Path("/app/uploads/demo-data")
DEMO_REPORT_ROOT = Path("/app/reports")
@dataclass(frozen=True)
class DemoCustomerTemplate:
name: str
specialty: str
street: str
postal_code: str
city: str
phone: str
email: str
hygiene_officer: str
quality_manager: str
operator: str
locations: list[dict[str, Any]]
contacts: list[dict[str, Any]]
device: dict[str, Any]
CUSTOMER_TEMPLATES: list[DemoCustomerTemplate] = [
DemoCustomerTemplate(
name="Zahnzentrum Alster",
specialty="Zahnarzt",
street="Alsterufer 18",
postal_code="20354",
city="Hamburg",
phone="040 5550010",
email="kontakt@zahnzentrum-alster.schubamed.de",
hygiene_officer="Dr. Jana Peters",
quality_manager="M. Kruse",
operator="Dr. Jana Peters",
locations=[
{"name": "Hauptpraxis", "street": "Alsterufer 18", "postal_code": "20354", "city": "Hamburg", "room": "Steri 1"},
{"name": "OP-Bereich", "street": "Alsterufer 18", "postal_code": "20354", "city": "Hamburg", "room": "OP 2"},
],
contacts=[
{"full_name": "Dr. Jana Peters", "function": "Betreiberin", "email": "jana.peters@schubamed.de", "phone": "040 5550011"},
{"full_name": "M. Kruse", "function": "QM-Beauftragte", "email": "qm.zahnzentrum.alster@schubamed.de", "phone": "040 5550012"},
],
device={
"manufacturer": "Euronda SpA",
"model": "E10.7",
"serial_number": "SN-DEMO-001",
"year_built": 2023,
"commissioned_on": date(2023, 6, 14),
"chamber_volume_liters": 24,
"steam_generation": "Eigendampferzeugung",
"water_treatment": "Vollentsalzung",
"documentation": "CF-Karte und PDF-Protokoll",
"supplier": "schubamed Medizintechnik",
},
),
DemoCustomerTemplate(
name="Urologie Zentrum Elbe",
specialty="Urologie",
street="Mönckebergstr. 11",
postal_code="20095",
city="Hamburg",
phone="040 5550020",
email="kontakt@urologie-elbe.schubamed.de",
hygiene_officer="Dr. Felix Brandt",
quality_manager="S. Lange",
operator="Dr. Felix Brandt",
locations=[
{"name": "Praxis Mitte", "street": "Mönckebergstr. 11", "postal_code": "20095", "city": "Hamburg", "room": "Steri A"},
],
contacts=[
{"full_name": "Dr. Felix Brandt", "function": "Betreiber", "email": "felix.brandt@schubamed.de", "phone": "040 5550021"},
],
device={
"manufacturer": "Euronda SpA",
"model": "E9",
"serial_number": "SN-DEMO-002",
"year_built": 2022,
"commissioned_on": date(2022, 11, 2),
"chamber_volume_liters": 18,
"steam_generation": "Generator integriert",
"water_treatment": "Wasserkonditionierung",
"documentation": "Digitale Dokumentation",
"supplier": "schubamed Medizintechnik",
},
),
DemoCustomerTemplate(
name="Orthopädie am Park",
specialty="Orthopädie",
street="Königsallee 44",
postal_code="40212",
city="Düsseldorf",
phone="0211 5550030",
email="kontakt@orthopaedie-park.schubamed.de",
hygiene_officer="Dr. Lea Sommer",
quality_manager="A. Hoffmann",
operator="Dr. Lea Sommer",
locations=[
{"name": "Ambulanz", "street": "Königsallee 44", "postal_code": "40212", "city": "Düsseldorf", "room": "Steri 1"},
{"name": "Behandlungszentrum", "street": "Kaiserswerther Str. 99", "postal_code": "40474", "city": "Düsseldorf", "room": "Steri 2"},
],
contacts=[
{"full_name": "Dr. Lea Sommer", "function": "Betreiberin", "email": "lea.sommer@schubamed.de", "phone": "0211 5550031"},
{"full_name": "A. Hoffmann", "function": "Hygienebeauftragte", "email": "hygiene.orthopaedie@schubamed.de", "phone": "0211 5550032"},
],
device={
"manufacturer": "MELAG",
"model": "Vacuklav 41 B+",
"serial_number": "SN-DEMO-003",
"year_built": 2021,
"commissioned_on": date(2021, 9, 8),
"chamber_volume_liters": 22,
"steam_generation": "Dampferzeuger intern",
"water_treatment": "VE-Wasser",
"documentation": "CF-Karte, USB-Export",
"supplier": "schubamed Medizintechnik",
},
),
DemoCustomerTemplate(
name="Dermatologie Rhein",
specialty="Dermatologie",
street="Breite Str. 8",
postal_code="50667",
city="Köln",
phone="0221 5550040",
email="kontakt@dermatologie-rhein.schubamed.de",
hygiene_officer="Dr. Sophie Keller",
quality_manager="D. Neumann",
operator="Dr. Sophie Keller",
locations=[
{"name": "Hautpraxis", "street": "Breite Str. 8", "postal_code": "50667", "city": "Köln", "room": "Steri"},
],
contacts=[
{"full_name": "Dr. Sophie Keller", "function": "Betreiberin", "email": "sophie.keller@schubamed.de", "phone": "0221 5550041"},
{"full_name": "D. Neumann", "function": "QM", "email": "qm.dermatologie.rhein@schubamed.de", "phone": "0221 5550042"},
],
device={
"manufacturer": "MELAG",
"model": "Vacuklav 44 B+",
"serial_number": "SN-DEMO-004",
"year_built": 2020,
"commissioned_on": date(2020, 4, 16),
"chamber_volume_liters": 24,
"steam_generation": "Eigendampferzeugung",
"water_treatment": "Osmose",
"documentation": "Digitale Dokumentation und Ausdruck",
"supplier": "schubamed Medizintechnik",
},
),
DemoCustomerTemplate(
name="HNO Zentrum Forum",
specialty="HNO",
street="Theatinerstr. 19",
postal_code="80333",
city="München",
phone="089 5550050",
email="kontakt@hno-forum.schubamed.de",
hygiene_officer="Dr. Tom Berger",
quality_manager="R. Wagner",
operator="Dr. Tom Berger",
locations=[
{"name": "Forum Praxis", "street": "Theatinerstr. 19", "postal_code": "80333", "city": "München", "room": "Steri 1"},
],
contacts=[
{"full_name": "Dr. Tom Berger", "function": "Betreiber", "email": "tom.berger@schubamed.de", "phone": "089 5550051"},
],
device={
"manufacturer": "MELAG",
"model": "PrimeLine",
"serial_number": "SN-DEMO-005",
"year_built": 2024,
"commissioned_on": date(2024, 3, 1),
"chamber_volume_liters": 29,
"steam_generation": "Generator integriert",
"water_treatment": "VE-Wasser",
"documentation": "USB-Export",
"supplier": "schubamed Medizintechnik",
},
),
DemoCustomerTemplate(
name="Gynäkologie Marienhof",
specialty="Gynäkologie",
street="Marienplatz 3",
postal_code="86150",
city="Augsburg",
phone="0821 5550060",
email="kontakt@gyn-marienhof.schubamed.de",
hygiene_officer="Dr. Miriam Wolf",
quality_manager="K. Braun",
operator="Dr. Miriam Wolf",
locations=[
{"name": "Frauenpraxis", "street": "Marienplatz 3", "postal_code": "86150", "city": "Augsburg", "room": "Steri"},
{"name": "Ambulanz Süd", "street": "Bürgermeister-Fischer-Str. 12", "postal_code": "86150", "city": "Augsburg", "room": "Steri 2"},
],
contacts=[
{"full_name": "Dr. Miriam Wolf", "function": "Betreiberin", "email": "miriam.wolf@schubamed.de", "phone": "0821 5550061"},
],
device={
"manufacturer": "MELAG",
"model": "ProLine",
"serial_number": "SN-DEMO-006",
"year_built": 2019,
"commissioned_on": date(2019, 8, 23),
"chamber_volume_liters": 18,
"steam_generation": "Kompaktgenerator",
"water_treatment": "VE-Wasser",
"documentation": "CF-Card",
"supplier": "schubamed Medizintechnik",
},
),
DemoCustomerTemplate(
name="Chirurgie Ost",
specialty="Chirurgie",
street="Lindenstr. 7",
postal_code="04109",
city="Leipzig",
phone="0341 5550070",
email="kontakt@chirurgie-ost.schubamed.de",
hygiene_officer="Dr. Paul Richter",
quality_manager="F. Scholz",
operator="Dr. Paul Richter",
locations=[
{"name": "OP-Zentrum", "street": "Lindenstr. 7", "postal_code": "04109", "city": "Leipzig", "room": "Steri OP"},
],
contacts=[
{"full_name": "Dr. Paul Richter", "function": "Betreiber", "email": "paul.richter@schubamed.de", "phone": "0341 5550071"},
{"full_name": "F. Scholz", "function": "Hygiene", "email": "hygiene.chirurgie.ost@schubamed.de", "phone": "0341 5550072"},
],
device={
"manufacturer": "W&H",
"model": "Lara XL",
"serial_number": "SN-DEMO-007",
"year_built": 2023,
"commissioned_on": date(2023, 2, 15),
"chamber_volume_liters": 17,
"steam_generation": "Dampferzeuger intern",
"water_treatment": "Mikrofiltration",
"documentation": "USB und Ausdruck",
"supplier": "schubamed Medizintechnik",
},
),
DemoCustomerTemplate(
name="Allgemeinmedizin West",
specialty="Allgemeinmedizin",
street="Bergstr. 25",
postal_code="70173",
city="Stuttgart",
phone="0711 5550080",
email="kontakt@allgemeinmedizin-west.schubamed.de",
hygiene_officer="Dr. Nina Beck",
quality_manager="J. Hartmann",
operator="Dr. Nina Beck",
locations=[
{"name": "Hausarztpraxis", "street": "Bergstr. 25", "postal_code": "70173", "city": "Stuttgart", "room": "Steri"},
],
contacts=[
{"full_name": "Dr. Nina Beck", "function": "Betreiberin", "email": "nina.beck@schubamed.de", "phone": "0711 5550081"},
],
device={
"manufacturer": "W&H",
"model": "Lisa",
"serial_number": "SN-DEMO-008",
"year_built": 2022,
"commissioned_on": date(2022, 7, 12),
"chamber_volume_liters": 22,
"steam_generation": "Eigendampferzeugung",
"water_treatment": "VE-Wasser",
"documentation": "Digital und Papier",
"supplier": "schubamed Medizintechnik",
},
),
DemoCustomerTemplate(
name="Augenärzte am Ring",
specialty="Augenarzt",
street="Ringstr. 52",
postal_code="50672",
city="Köln",
phone="0221 5550090",
email="kontakt@augenaerzte-ring.schubamed.de",
hygiene_officer="Dr. Karin Otto",
quality_manager="M. Franke",
operator="Dr. Karin Otto",
locations=[
{"name": "Augenzentrum", "street": "Ringstr. 52", "postal_code": "50672", "city": "Köln", "room": "Steri 1"},
{"name": "Laserzentrum", "street": "Ringstr. 54", "postal_code": "50672", "city": "Köln", "room": "Steri 2"},
],
contacts=[
{"full_name": "Dr. Karin Otto", "function": "Betreiberin", "email": "karin.otto@schubamed.de", "phone": "0221 5550091"},
{"full_name": "M. Franke", "function": "QM", "email": "qm.augen@schubamed.de", "phone": "0221 5550092"},
],
device={
"manufacturer": "Mocom",
"model": "B Classic",
"serial_number": "SN-DEMO-009",
"year_built": 2021,
"commissioned_on": date(2021, 5, 20),
"chamber_volume_liters": 12,
"steam_generation": "Kompaktgenerator",
"water_treatment": "Vollentsalzung",
"documentation": "USB-Export",
"supplier": "schubamed Medizintechnik",
},
),
DemoCustomerTemplate(
name="MVZ Medikon",
specialty="MVZ",
street="Forum 9",
postal_code="90402",
city="Nürnberg",
phone="0911 5550100",
email="kontakt@mvz-medikon.schubamed.de",
hygiene_officer="Dr. Lara Stein",
quality_manager="C. Meier",
operator="Dr. Lara Stein",
locations=[
{"name": "Hauptstandort", "street": "Forum 9", "postal_code": "90402", "city": "Nürnberg", "room": "Steri A"},
{"name": "Nebenstandort", "street": "Forum 11", "postal_code": "90402", "city": "Nürnberg", "room": "Steri B"},
],
contacts=[
{"full_name": "Dr. Lara Stein", "function": "Betreiberin", "email": "lara.stein@schubamed.de", "phone": "0911 5550101"},
{"full_name": "C. Meier", "function": "Hygiene", "email": "hygiene.mvz@schubamed.de", "phone": "0911 5550102"},
],
device={
"manufacturer": "Kronos",
"model": "B23",
"serial_number": "SN-DEMO-010",
"year_built": 2024,
"commissioned_on": date(2024, 1, 11),
"chamber_volume_liters": 23,
"steam_generation": "Eigendampferzeugung",
"water_treatment": "VE-Wasser",
"documentation": "Hybrid",
"supplier": "schubamed Medizintechnik",
},
),
]
EQUIPMENT_TEMPLATES: list[dict[str, Any]] = [
{
"kind": EquipmentKind.temperature_logger,
"manufacturer": "EBRO",
"model": "EBI 11",
"serial_number": "DEMO-EBI11-001",
"calibrated_on": date(2025, 1, 17),
"calibration_due_on": date(2026, 1, 17),
"status": EquipmentStatus.green,
"notes": "Demo-Temperaturlogger",
},
{
"kind": EquipmentKind.temperature_logger,
"manufacturer": "EBRO",
"model": "EBI 11",
"serial_number": "DEMO-EBI11-002",
"calibrated_on": date(2025, 2, 2),
"calibration_due_on": date(2026, 2, 2),
"status": EquipmentStatus.green,
"notes": "Demo-Temperaturlogger",
},
{
"kind": EquipmentKind.pressure_logger,
"manufacturer": "EBRO",
"model": "Drucklogger",
"serial_number": "DEMO-PR-001",
"calibrated_on": date(2025, 1, 21),
"calibration_due_on": date(2026, 1, 21),
"status": EquipmentStatus.green,
"notes": "Demo-Drucklogger",
},
{
"kind": EquipmentKind.sensor,
"manufacturer": "Mettler Toledo",
"model": "Waage",
"serial_number": "DEMO-SCALE-001",
"calibrated_on": date(2024, 12, 12),
"calibration_due_on": date(2025, 12, 12),
"status": EquipmentStatus.yellow,
"notes": "Demo-Waage",
},
{
"kind": EquipmentKind.sensor,
"manufacturer": "Mettler Toledo",
"model": "Leitwertmessgerät",
"serial_number": "DEMO-COND-001",
"calibrated_on": date(2025, 3, 4),
"calibration_due_on": date(2026, 3, 4),
"status": EquipmentStatus.green,
"notes": "Demo-Leitwertmessgerät",
},
{
"kind": EquipmentKind.sensor,
"manufacturer": "Trotec",
"model": "Raumklimamessgerät",
"serial_number": "DEMO-CLIMATE-001",
"calibrated_on": date(2024, 11, 1),
"calibration_due_on": date(2025, 11, 1),
"status": EquipmentStatus.red,
"notes": "Demo-Raumklimamessgerät",
},
]
class DemoDataService:
def __init__(self, session: Session, upload_root: Path | None = None, report_root: Path | None = None) -> None:
self.session = session
self.upload_root = upload_root or DEMO_UPLOAD_ROOT.parent
self.report_root = report_root or DEMO_REPORT_ROOT
self.demo_upload_root = self.upload_root / "demo-data"
def run(
self,
*,
customers: int = 10,
devices: int = 10,
validations: int = 20,
reports: bool = False,
images: bool = False,
reset: bool = False,
) -> dict[str, int]:
if reset:
self.reset()
created_customers = self.ensure_customers(max(customers, 10))
created_equipment = self.ensure_equipment()
created_devices = self.ensure_devices(max(devices, 10), created_customers)
created_validations = self.ensure_validations(max(validations, 20), created_customers, created_devices, images=images)
self.session.commit()
if reports:
self._generate_reports(created_validations)
return {
"customers": len(created_customers),
"devices": len(created_devices),
"validations": len(created_validations),
"equipment": len(created_equipment),
}
def reset(self) -> None:
demo_validation_ids = self.session.scalars(
select(Validation.id).where(
Validation.report_number.like(f"{DEMO_REPORT_PREFIX}%")
| Validation.notes.like(f"%{DEMO_TAG}%")
)
).all()
if demo_validation_ids:
self.session.execute(delete(Validation).where(Validation.id.in_(demo_validation_ids)))
self.session.execute(
delete(Equipment).where(Equipment.serial_number.like("DEMO-%") | Equipment.notes.like(f"%{DEMO_TAG}%"))
)
self.session.execute(
delete(Device).where(Device.serial_number.like("SN-DEMO-%") | Device.notes.like(f"%{DEMO_TAG}%"))
)
self.session.execute(
delete(Contact).where(
Contact.email.like("demo-%@schubamed.de") | Contact.notes.like(f"%{DEMO_TAG}%")
)
)
self.session.execute(
delete(Customer).where(
Customer.email.like("demo-%@schubamed.de") | Customer.notes.like(f"%{DEMO_TAG}%")
)
)
self.session.commit()
if self.demo_upload_root.exists():
shutil.rmtree(self.demo_upload_root)
self.report_root.mkdir(parents=True, exist_ok=True)
for pdf in self.report_root.glob(f"{DEMO_REPORT_PREFIX}*.pdf"):
pdf.unlink()
def ensure_customers(self, count: int) -> list[Customer]:
ensured: list[Customer] = []
for index in range(count):
template = CUSTOMER_TEMPLATES[index % len(CUSTOMER_TEMPLATES)]
occurrence = index // len(CUSTOMER_TEMPLATES)
customer = self._ensure_customer(template, occurrence, index)
ensured.append(customer)
return ensured
def ensure_equipment(self) -> list[Equipment]:
items: list[Equipment] = []
for template in EQUIPMENT_TEMPLATES:
equipment = self.session.scalar(
select(Equipment).where(Equipment.serial_number == template["serial_number"])
)
if equipment is None:
equipment = Equipment(**template)
equipment.notes = f"{template['notes']} {DEMO_TAG}"
self.session.add(equipment)
self.session.flush()
items.append(equipment)
return items
def ensure_devices(self, count: int, customers: list[Customer]) -> list[Device]:
devices: list[Device] = []
all_locations = {customer.id: list(self.session.scalars(select(Location).where(Location.customer_id == customer.id))) for customer in customers}
for index in range(count):
customer = customers[index % len(customers)]
template = CUSTOMER_TEMPLATES[index % len(CUSTOMER_TEMPLATES)].device
occurrence = index // len(CUSTOMER_TEMPLATES)
serial_number = template["serial_number"] if occurrence == 0 else f"{template['serial_number']}-{occurrence + 1}"
device = self.session.scalar(select(Device).where(Device.serial_number == serial_number))
if device is None:
location_candidates = all_locations.get(customer.id, [])
location_id = location_candidates[0].id if location_candidates else None
device_payload = deepcopy(template)
device_payload["serial_number"] = serial_number
device_payload["customer_id"] = customer.id
device_payload["location_id"] = location_id
device = Device(**device_payload)
device.notes = f"{DEMO_TAG} {customer.name}"
self.session.add(device)
self.session.flush()
devices.append(device)
return devices
def ensure_validations(
self,
count: int,
customers: list[Customer],
devices: list[Device],
*,
images: bool = False,
) -> list[Validation]:
validations: list[Validation] = []
report_number_index = 1
for index in range(count):
template = CUSTOMER_TEMPLATES[index % len(CUSTOMER_TEMPLATES)]
customer = customers[index % len(customers)]
device = devices[index % len(devices)]
locations = list(self.session.scalars(select(Location).where(Location.customer_id == customer.id)))
contacts = list(self.session.scalars(select(Contact).where(Contact.customer_id == customer.id)))
location = locations[index % len(locations)] if locations else None
contact = contacts[index % len(contacts)] if contacts else None
report_number = f"{DEMO_REPORT_PREFIX}-{report_number_index:03d}"
report_number_index += 1
validation = self.session.scalar(select(Validation).where(Validation.report_number == report_number))
if validation is None:
validation = Validation(
report_number=report_number,
customer_id=customer.id,
location_id=location.id if location else None,
contact_id=contact.id if contact else None,
device_id=device.id,
validation_type="Erstvalidierung" if index % 2 == 0 else "Revalidierung",
performed_on=date.today() - relativedelta(months=6 + index),
examiner_name="Dr. Lara Stein",
operator_name=template.operator,
participants=f"{customer.name} - Team",
status=[
ValidationStatus.draft.value,
ValidationStatus.approved.value,
ValidationStatus.completed.value,
][index % 3],
result="bestanden" if index % 3 else "bestanden mit Auflagen",
revalidation_interval_months=24,
equipment_ids=[equipment.id for equipment in self.session.scalars(select(Equipment).limit(3))],
environment_conditions={
"room_temperature": 22 + (index % 3),
"humidity": 48 + (index % 5),
"test_time": f"{8 + (index % 3)}:30",
"checks": [
{"text": "Raumbedingungen stabil", "value": "yes", "comment": ""},
{"text": "Aufstellort frei zugänglich", "value": "yes", "comment": ""},
],
},
documentation_checklist=self._checklist("documentation_control", index),
performance_checklist=self._checklist("sterilizer_description", index),
programs=[
{"name": "Vakuumtest", "selected": True, "custom": False},
{"name": "Bowie-Dick / Leerkammerprofil", "selected": index % 2 == 0, "custom": False},
{"name": "134 C hohl verpackt", "selected": True, "custom": False},
],
loading_patterns=self._loading_patterns(index),
measurement_data=self._measurement_data(index),
drying={"start_weight": 12.5, "end_weight": 12.1, "difference": 0.4, "assessment": "in Ordnung", "comment": ""},
recommendations=[
{"number": 1, "text": "Routinekontrolle dokumentieren", "deadline": "6 Monate", "status": "offen"}
] if index % 4 == 0 else [],
attachments=self._attachments_for_validation(index, images=images),
notes=DEMO_TAG,
)
self.session.add(validation)
self.session.flush()
ValidationWorkflowService(self.session).apply_revalidation_date(validation)
validations.append(validation)
return validations
def _ensure_customer(self, template: DemoCustomerTemplate, occurrence: int, index: int) -> Customer:
email = template.email if occurrence == 0 else f"demo-{index + 1:02d}@schubamed.de"
customer = self.session.scalar(select(Customer).where(Customer.email == email))
if customer is None:
customer = Customer(
customer_type=CustomerType.practice,
name=template.name if occurrence == 0 else f"{template.name} {occurrence + 1}",
street=template.street,
postal_code=template.postal_code,
city=template.city,
phone=template.phone,
email=email,
hygiene_officer=template.hygiene_officer,
quality_manager=template.quality_manager,
notes=f"{DEMO_TAG} {template.specialty}",
)
self.session.add(customer)
self.session.flush()
for loc_index, location_payload in enumerate(template.locations, start=1):
location = self.session.scalar(
select(Location).where(
Location.customer_id == customer.id,
Location.name == location_payload["name"],
)
)
if location is None:
self.session.add(Location(customer_id=customer.id, **location_payload))
for contact_payload in template.contacts:
contact = self.session.scalar(
select(Contact).where(
Contact.customer_id == customer.id,
Contact.full_name == contact_payload["full_name"],
)
)
if contact is None:
self.session.add(
Contact(
customer_id=customer.id,
full_name=contact_payload["full_name"],
function=contact_payload["function"],
email=contact_payload["email"],
phone=contact_payload["phone"],
notes=DEMO_TAG,
)
)
self.session.flush()
return customer
def _checklist(self, key: str, index: int) -> list[dict[str, Any]]:
bundle = ReportTemplateService(self.session).ensure_default_template()
template = next((item for item in bundle.checklists if item.checklist_key == key), None)
if template is None:
return []
values = ["yes", "yes", "na"] if index % 2 == 0 else ["yes", "na", "yes"]
return [
{
"number": item["number"],
"text": item["text"],
"value": values[(item["number"] - 1) % len(values)],
"comment": "",
}
for item in template.items
]
def _loading_patterns(self, index: int) -> list[dict[str, Any]]:
return [
{
"run": 1,
"pattern": "Standard",
"description": f"Demo-Beladung {index + 1}",
"images": [],
},
{
"run": 2,
"pattern": "Standard",
"description": "",
"images": [],
},
{
"run": 3,
"pattern": "Standard",
"description": "",
"images": [],
},
]
def _measurement_data(self, index: int) -> list[dict[str, Any]]:
base_temperature = 132 + (index % 3)
return [
{
"test_run": "Vakuumtest",
"start_time": "08:00",
"end_time": "08:08",
"duration": "00:08",
"leak_rate": "0.4",
"result": "bestanden",
},
{
"test_run": "Testlauf 1",
"start_time": "09:00",
"end_time": "09:31",
"duration": "00:31",
"minimum_temperature": base_temperature,
"maximum_temperature": base_temperature + 2,
"temperature_band": "2.0",
"holding_time": "3:00",
"pressure": "2.1",
"result": "bestanden",
},
]
def _attachments_for_validation(self, index: int, *, images: bool) -> list[dict[str, Any]]:
if not images or index >= 5:
return []
image_dir = self.demo_upload_root / "images"
image_dir.mkdir(parents=True, exist_ok=True)
image_path = image_dir / f"demo-figure-{index + 1}.svg"
if not image_path.exists():
image_path.write_text(
"\n".join(
[
'<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="800" viewBox="0 0 1200 800">',
'<rect width="1200" height="800" fill="#f6f7f2"/>',
'<rect x="60" y="60" width="1080" height="680" rx="18" fill="#ffffff" stroke="#bfc5bd" stroke-width="3"/>',
'<text x="100" y="150" font-family="Arial, sans-serif" font-size="44" fill="#2f3b35">SCHUBAMED Demo-Bild</text>',
f'<text x="100" y="230" font-family="Arial, sans-serif" font-size="32" fill="#4d5b54">Validierung {index + 1}</text>',
"</svg>",
]
),
encoding="utf-8",
)
return [
{
"category": "Beladung",
"filename": image_path.name,
"content_type": "image/svg+xml",
"description": f"Demo-Abbildung {index + 1}",
"order": 1,
"storage_path": str(image_path),
}
]
def _generate_reports(self, validations: list[Validation]) -> None:
self.report_root.mkdir(parents=True, exist_ok=True)
ReportTemplateService(self.session).ensure_default_template()
for validation in validations:
OrionReportService(self.session, self.report_root).render_pdf(validation.id)

View file

@ -36,11 +36,13 @@ class CrudService:
safe_page = max(page, 1)
safe_page_size = min(max(page_size, 1), 100)
offset = (safe_page - 1) * safe_page_size
total = self.repository.count(search)
return {
"items": self.repository.list(safe_page_size, offset, search),
"total": self.repository.count(search),
"total": total,
"page": safe_page,
"page_size": safe_page_size,
"pages": max((total + safe_page_size - 1) // safe_page_size, 1),
}
def create(self, data: dict) -> ModelT:

View file

@ -0,0 +1,256 @@
from __future__ import annotations
from copy import deepcopy
from datetime import date
from sqlalchemy import and_, func, select
from sqlalchemy.orm import Session
from app.models.contact import Contact
from app.models.customer import Customer
from app.models.device import Device
from app.models.equipment import Equipment, EquipmentKind
from app.models.location import Location
from app.models.user import User
from app.models.validation import Validation, ValidationStatus
from app.modules.orion.template_service import ReportTemplateService
from app.schemas.domain import QuickStartCreateRequest, QuickStartCustomerData, QuickStartValidationSummary
from app.services.validation_workflow import ValidationWorkflowService
class QuickStartService:
def __init__(self, session: Session) -> None:
self.session = session
def customer_data(self, customer_id: str) -> QuickStartCustomerData:
customer = self._customer(customer_id)
locations = list(
self.session.scalars(
select(Location).where(Location.customer_id == customer.id).order_by(Location.name.asc())
)
)
contacts = list(
self.session.scalars(
select(Contact).where(Contact.customer_id == customer.id).order_by(Contact.full_name.asc())
)
)
devices = list(
self.session.scalars(
select(Device).where(Device.customer_id == customer.id).order_by(Device.serial_number.asc())
)
)
validations = self._validation_summaries([device.id for device in devices])
return QuickStartCustomerData(
customer=customer,
locations=locations,
contacts=contacts,
devices=devices,
validations=validations,
)
def device_last_validation(self, device_id: str) -> QuickStartValidationSummary | None:
return self._last_validation(device_id)
def create_validation(self, payload: QuickStartCreateRequest, examiner: User) -> Validation:
customer = self._customer(str(payload.customer_id))
devices = list(
self.session.scalars(
select(Device).where(Device.customer_id == customer.id).order_by(Device.serial_number.asc())
)
)
device = self._device(str(payload.device_id)) if payload.device_id else self._single_or_default(devices)
if device is None:
raise ValueError("Kein Gerät verfügbar.")
locations = list(
self.session.scalars(
select(Location).where(Location.customer_id == customer.id).order_by(Location.name.asc())
)
)
contacts = list(
self.session.scalars(
select(Contact).where(Contact.customer_id == customer.id).order_by(Contact.full_name.asc())
)
)
location = self._location(str(payload.location_id)) if payload.location_id else self._single_or_default(locations)
contact = self._contact(str(payload.contact_id)) if payload.contact_id else self._single_or_default(contacts)
base = self._base_validation(device.id, payload.validation_type)
bundle = ReportTemplateService(self.session).ensure_default_template()
validation = Validation(
report_number=self._next_report_number(),
customer_id=customer.id,
location_id=location.id if location else (locations[0].id if locations else None),
contact_id=contact.id if contact else None,
device_id=device.id,
validation_type=payload.validation_type,
performed_on=date.today(),
examiner_name=examiner.full_name,
examiner_id=examiner.id,
operator_name=customer.quality_manager or customer.hygiene_officer or examiner.full_name,
status=ValidationStatus.draft.value,
result="offen",
revalidation_interval_months=base.revalidation_interval_months if base else 24,
next_validation_manually_overridden=False,
version=1 if base is None else base.version + 1,
previous_validation_id=base.id if base else None,
equipment_ids=list(base.equipment_ids) if base and base.equipment_ids else self._default_equipment_ids(),
environment_conditions=deepcopy(base.environment_conditions) if base else {},
documentation_checklist=deepcopy(base.documentation_checklist) if base else self._template_checklist(bundle, "documentation_checklist"),
performance_checklist=deepcopy(base.performance_checklist) if base else self._template_checklist(bundle, "performance_checklist"),
programs=deepcopy(base.programs) if base else self._default_programs(),
loading_patterns=deepcopy(base.loading_patterns) if base else self._default_loading_patterns(),
measurement_data=[],
drying={},
recommendations=deepcopy(base.recommendations) if base else [],
attachments=[],
)
self.session.add(validation)
self.session.flush()
ValidationWorkflowService(self.session).apply_revalidation_date(validation)
return validation
def _customer(self, customer_id: str) -> Customer:
customer = self.session.get(Customer, customer_id)
if customer is None:
raise ValueError("Kunde nicht gefunden.")
return customer
def _device(self, device_id: str) -> Device:
device = self.session.get(Device, device_id)
if device is None:
raise ValueError("Gerät nicht gefunden.")
return device
def _location(self, location_id: str) -> Location:
location = self.session.get(Location, location_id)
if location is None:
raise ValueError("Standort nicht gefunden.")
return location
def _contact(self, contact_id: str) -> Contact:
contact = self.session.get(Contact, contact_id)
if contact is None:
raise ValueError("Ansprechpartner nicht gefunden.")
return contact
def _single_or_default(self, items):
if len(items) == 1:
return items[0]
return None
def _last_validation(self, device_id: str) -> QuickStartValidationSummary | None:
validation = self.session.scalar(
select(Validation)
.where(
and_(
Validation.device_id == device_id,
Validation.status.in_([ValidationStatus.approved.value, ValidationStatus.completed.value]),
)
)
.order_by(Validation.performed_on.desc().nulls_last(), Validation.updated_at.desc())
)
if validation is None:
return None
return self._summary(validation)
def _validation_summaries(self, device_ids: list[str]) -> list[QuickStartValidationSummary]:
if not device_ids:
return []
validations = list(
self.session.scalars(
select(Validation)
.where(Validation.device_id.in_(device_ids))
.order_by(Validation.performed_on.desc().nulls_last(), Validation.updated_at.desc())
.limit(10)
)
)
return [self._summary(item) for item in validations]
def _summary(self, validation: Validation) -> QuickStartValidationSummary:
return QuickStartValidationSummary(
id=validation.id,
device_id=validation.device_id,
report_number=validation.report_number,
performed_on=validation.performed_on,
result=validation.result,
next_validation_on=validation.next_validation_on,
status=validation.status,
validation_type=validation.validation_type,
equipment_ids=list(validation.equipment_ids or []),
)
def _base_validation(self, device_id: str, validation_type: str) -> Validation | None:
if validation_type not in {"Revalidierung", "Leistungsbeurteilung"}:
return None
return self.session.scalar(
select(Validation)
.where(
and_(
Validation.device_id == device_id,
Validation.status.in_([ValidationStatus.approved.value, ValidationStatus.completed.value]),
)
)
.order_by(Validation.performed_on.desc().nulls_last(), Validation.updated_at.desc())
)
def _next_report_number(self) -> str:
total = self.session.scalar(select(func.count()).select_from(Validation)) or 0
return f"VAL-{total + 1:05d}"
def _default_equipment_ids(self) -> list[str]:
equipment = list(
self.session.scalars(
select(Equipment).where(Equipment.kind == EquipmentKind.temperature_logger).order_by(Equipment.serial_number.asc())
)
)
equipment.extend(
list(
self.session.scalars(
select(Equipment).where(Equipment.kind == EquipmentKind.pressure_logger).order_by(Equipment.serial_number.asc())
)
)
)
selected: list[str] = []
temp_count = 0
pressure_count = 0
for item in equipment:
if item.kind == EquipmentKind.temperature_logger and temp_count < 5:
selected.append(item.id)
temp_count += 1
elif item.kind == EquipmentKind.pressure_logger and pressure_count < 1:
selected.append(item.id)
pressure_count += 1
return selected
def _template_checklist(self, bundle, key: str) -> list[dict]:
checklist_key = {
"documentation_checklist": "documentation_control",
"performance_checklist": "sterilizer_description",
}.get(key, key)
template = next((item for item in bundle.checklists if item.checklist_key == checklist_key), None)
if template is None:
return []
return [
{
"template_key": template.checklist_key,
"template_title": template.title,
"text": item,
"value": "na",
"comment": "",
}
for item in template.items
]
def _default_programs(self) -> list[dict]:
return [
{"name": "Vakuumtest", "selected": True, "custom": False},
{"name": "Bowie-Dick / Leerkammerprofil", "selected": True, "custom": False},
{"name": "134 C hohl verpackt", "selected": True, "custom": False},
]
def _default_loading_patterns(self) -> list[dict]:
return [
{"run": 1, "pattern": "Standardbeladung", "description": "", "images": []},
{"run": 2, "pattern": "Standardbeladung", "description": "", "images": []},
{"run": 3, "pattern": "Standardbeladung", "description": "", "images": []},
]

View file

@ -7,7 +7,7 @@ from datetime import date, datetime
from uuid import uuid4
from dateutil.relativedelta import relativedelta
from sqlalchemy import and_, or_, select
from sqlalchemy import and_, func, or_, select
from sqlalchemy.orm import Session
from app.models.contact import Contact
@ -224,9 +224,17 @@ class ValidationWorkflowService:
statement = statement.order_by(sort_column.asc())
else:
statement = statement.order_by(sort_column.desc())
total = len(list(self.session.scalars(count_statement)))
total = self.session.scalar(
select(func.count()).select_from(count_statement.order_by(None).subquery())
) or 0
items = list(self.session.scalars(statement.offset((page - 1) * page_size).limit(page_size)))
return {"items": items, "total": total, "page": page, "page_size": page_size}
return {
"items": items,
"total": total,
"page": page,
"page_size": page_size,
"pages": max((total + page_size - 1) // page_size, 1),
}
def revalidation_status(self, validation: Validation) -> str:
if not validation.next_validation_on:

View file

@ -2,6 +2,4 @@
set -eu
alembic upgrade head
python -m app.db.seed
exec "$@"

View file

@ -0,0 +1,99 @@
from __future__ import annotations
from sqlalchemy import create_engine, func, select
from sqlalchemy.orm import Session
from app.db.base import Base
from app.models.contact import Contact
from app.models.customer import Customer, CustomerType
from app.models.device import Device
from app.models.equipment import Equipment
from app.models.validation import Validation
from app import cli as app_cli
from app.services.demo_data import DemoDataService
def session() -> Session:
engine = create_engine("sqlite+pysqlite:///:memory:")
Base.metadata.create_all(engine)
return Session(engine)
def test_demo_data_cli_parser_accepts_expected_options():
args = app_cli.build_parser().parse_args(
[
"demo-data",
"--customers",
"10",
"--devices",
"10",
"--validations",
"20",
"--reports",
"--images",
]
)
assert args.command == "demo-data"
assert args.customers == 10
assert args.devices == 10
assert args.validations == 20
assert args.reports is True
assert args.images is True
def test_demo_data_service_is_idempotent_and_creates_realistic_data(tmp_path):
db = session()
service = DemoDataService(db, upload_root=tmp_path / "uploads", report_root=tmp_path / "reports")
summary_first = service.run(customers=10, devices=10, validations=20, images=True)
assert summary_first["customers"] == 10
assert summary_first["devices"] == 10
assert summary_first["validations"] == 20
assert db.scalar(select(func.count()).select_from(Customer)) == 10
assert db.scalar(select(func.count()).select_from(Device)) == 10
assert db.scalar(select(func.count()).select_from(Equipment)) >= 6
assert db.scalar(select(func.count()).select_from(Validation)) == 20
assert db.scalar(select(func.count()).select_from(Contact)) >= 10
assert list((tmp_path / "uploads").rglob("*.svg"))
summary_second = service.run(customers=10, devices=10, validations=20, images=True)
assert summary_second["customers"] == 10
assert db.scalar(select(func.count()).select_from(Customer)) == 10
assert db.scalar(select(func.count()).select_from(Device)) == 10
assert db.scalar(select(func.count()).select_from(Validation)) == 20
def test_demo_data_reset_removes_only_demo_rows(tmp_path):
db = session()
real_customer = Customer(
customer_type=CustomerType.practice,
name="Reale Praxis",
email="real@example.com",
)
db.add(real_customer)
db.flush()
service = DemoDataService(db, upload_root=tmp_path / "uploads", report_root=tmp_path / "reports")
service.run(customers=10, devices=10, validations=20, images=True)
service.reset()
assert db.scalar(select(Customer).where(Customer.email == "real@example.com")) is not None
assert db.scalar(select(Customer).where(Customer.notes.like("%DEMO_DATA%"))) is None
assert db.scalar(select(Device).where(Device.notes.like("%DEMO_DATA%"))) is None
assert db.scalar(select(Validation).where(Validation.notes.like("%DEMO_DATA%"))) is None
def test_demo_data_cli_command_uses_sessionlocal(monkeypatch):
db = session()
monkeypatch.setattr(app_cli, "SessionLocal", lambda: db)
args = app_cli.build_parser().parse_args(["demo-data", "--customers", "10", "--devices", "10", "--validations", "20"])
exit_code = app_cli.cmd_demo_data(args)
assert exit_code == 0
assert db.scalar(select(func.count()).select_from(Customer)) == 10
assert db.scalar(select(func.count()).select_from(Device)) == 10
assert db.scalar(select(func.count()).select_from(Validation)) == 20

View file

@ -20,10 +20,11 @@ from app.models.validation import Validation, ValidationStatus
from app.services.validation_workflow import ValidationWorkflowService
from app.services.auth_service import AuthService
from app.services.reference_masterdata import ReferenceMasterdataImportService
from app.services.quickstart_service import QuickStartService
from app.api.v1.auth import login as auth_login
from app.api.v1 import domain as domain_api
from app.schemas.auth import LoginRequest
from app.schemas.domain import UserCreate, UserUpdate, ValidationCreate
from app.schemas.domain import QuickStartCreateRequest, UserCreate, UserUpdate, ValidationCreate
from app.modules.orion.service import OrionReportService
from app.modules.orion.assets import SCHUBAMED_LOGO_PATH, schubamed_logo_uri
from app.modules.orion.template_service import REPORT_SECTIONS, ReportTemplateService
@ -277,6 +278,36 @@ def test_user_list_pagination_and_filters_work():
assert role_filtered["items"][0].role == UserRole.ADMIN.value
def test_paginated_lists_expose_pages_for_masterdata_and_validations():
db = session()
customer, location, device = seed(db)
db.add(valid_validation(customer, location, device))
db.flush()
customers = domain_api.list_customers(params={"page": 1, "page_size": 20, "search": None}, session=db)
devices = domain_api.list_devices(params={"page": 1, "page_size": 20, "search": None}, session=db)
validations = domain_api.list_validations(
search=None,
page=1,
page_size=20,
sort_by="created_at",
sort_order="desc",
status=None,
customer_id=None,
device_id=None,
validation_type=None,
result=None,
date_from=None,
date_to=None,
overdue_only=False,
session=db,
)
assert customers["pages"] == 1
assert devices["pages"] == 1
assert validations["pages"] == 1
def test_admin_can_create_users_with_supported_roles():
db = session()
admin = User(
@ -636,6 +667,144 @@ def test_reference_masterdata_import_can_create_validation():
assert validation.status == ValidationStatus.draft.value
def test_quickstart_customer_data_and_validation_creation():
db = session()
reference = next(
candidate
for parent in Path(__file__).resolve().parents
if (candidate := parent / "docs/reference/reports/Erstvalidierung_Dr.Durmaz_Steri_12-25.docx").exists()
)
ReferenceMasterdataImportService(db).import_reference_docx(reference, create_validation=True)
customer = db.scalar(select(Customer).where(Customer.name == "Urologische Praxis Dr. Durmaz"))
assert customer is not None
customer_data = QuickStartService(db).customer_data(customer.id)
assert customer_data.locations
assert customer_data.contacts
assert customer_data.devices
assert customer_data.validations
admin = User(
email="quickstart-admin@schubamed.de",
first_name="Quickstart",
last_name="Admin",
role=UserRole.ADMIN.value,
password_hash="hash",
is_active=True,
must_change_password=False,
)
db.add(admin)
db.flush()
created = QuickStartService(db).create_validation(
QuickStartCreateRequest(
customer_id=customer.id,
location_id=customer_data.locations[0].id,
contact_id=customer_data.contacts[0].id,
device_id=customer_data.devices[0].id,
validation_type="Erstvalidierung",
),
examiner=admin,
)
db.commit()
assert created.id is not None
assert created.status == ValidationStatus.draft.value
assert created.customer_id == customer.id
assert created.examiner_id == admin.id
assert created.documentation_checklist
assert created.programs
assert created.loading_patterns
def test_quickstart_auto_selects_single_customer_masterdata():
db = session()
customer, location, device = seed(db)
contact = seed_contact(db, customer)
admin = User(
email="single-data-admin@schubamed.de",
first_name="Quickstart",
last_name="Admin",
role=UserRole.ADMIN.value,
password_hash="hash",
is_active=True,
must_change_password=False,
)
db.add(admin)
db.flush()
created = QuickStartService(db).create_validation(
QuickStartCreateRequest(
customer_id=customer.id,
validation_type="Erstvalidierung",
),
examiner=admin,
)
assert created.customer_id == customer.id
assert created.location_id == location.id
assert created.contact_id == contact.id
assert created.device_id == device.id
def test_quickstart_device_last_validation_returns_latest_completed_validation():
db = session()
customer, location, device = seed(db)
draft = valid_validation(customer, location, device)
draft.status = ValidationStatus.draft.value
completed = valid_validation(customer, location, device)
completed.report_number = "VAL-PAST"
completed.status = ValidationStatus.completed.value
completed.performed_on = date(2026, 1, 1)
db.add_all([draft, completed])
db.flush()
summary = QuickStartService(db).device_last_validation(device.id)
assert summary is not None
assert summary.report_number == "VAL-PAST"
assert summary.device_id == device.id
def test_quickstart_revalidation_copies_structured_data_but_not_measurements():
db = session()
customer, location, device = seed(db)
admin = User(
email="revalidation-admin@schubamed.de",
first_name="Quickstart",
last_name="Admin",
role=UserRole.ADMIN.value,
password_hash="hash",
is_active=True,
must_change_password=False,
)
base = valid_validation(customer, location, device)
base.status = ValidationStatus.approved.value
base.documentation_checklist = [{"text": "Prüfung A", "value": "yes"}]
base.performance_checklist = [{"text": "Prüfung B", "value": "no"}]
base.programs = [{"name": "Vakuumtest", "selected": True}]
base.loading_patterns = [{"run": 1, "pattern": "Standard", "description": "Basis", "images": ["x"]}]
base.measurement_data = [{"field": "temperatur"}]
base.attachments = [{"filename": "bild.png"}]
db.add_all([admin, base])
db.flush()
created = QuickStartService(db).create_validation(
QuickStartCreateRequest(
customer_id=customer.id,
device_id=device.id,
validation_type="Revalidierung",
),
examiner=admin,
)
assert created.previous_validation_id == base.id
assert created.version == 2
assert created.documentation_checklist == base.documentation_checklist
assert created.performance_checklist == base.performance_checklist
assert created.programs == base.programs
assert created.loading_patterns == base.loading_patterns
assert created.measurement_data == []
assert created.attachments == []
def test_revalidation_date_uses_calendar_months():
db = session()
customer, location, device = seed(db)

View file

@ -0,0 +1 @@
gYkJsTjiH4z33DmMxskx1

View file

@ -0,0 +1,25 @@
{
"/(app)/contacts/page": "/contacts",
"/(app)/customers/page": "/customers",
"/(app)/dashboard/page": "/dashboard",
"/(app)/devices/page": "/devices",
"/(app)/documents/page": "/documents",
"/(app)/equipment/page": "/equipment",
"/(app)/locations/page": "/locations",
"/(app)/profile/security/page": "/profile/security",
"/(app)/users/page": "/users",
"/(app)/validations/[id]/edit/page": "/validations/[id]/edit",
"/(app)/validations/[id]/preview/page": "/validations/[id]/preview",
"/(app)/validations/new/page": "/validations/new",
"/(app)/validations/page": "/validations",
"/(app)/validations/quick-start/page": "/validations/quick-start",
"/(auth)/login/page": "/login",
"/_global-error/page": "/_global-error",
"/_not-found/page": "/_not-found",
"/api/login/route": "/api/login",
"/api/logout/route": "/api/logout",
"/api/me/route": "/api/me",
"/api/v1/[...path]/route": "/api/v1/[...path]",
"/icon.svg/route": "/icon.svg",
"/page": "/"
}

View file

@ -0,0 +1,22 @@
{
"pages": {
"/_app": []
},
"devFiles": [],
"polyfillFiles": [
"static/chunks/0cz1d0mv5g_q7.js"
],
"lowPriorityFiles": [
"static/gYkJsTjiH4z33DmMxskx1/_buildManifest.js",
"static/gYkJsTjiH4z33DmMxskx1/_ssgManifest.js",
"static/gYkJsTjiH4z33DmMxskx1/_clientMiddlewareManifest.js"
],
"rootMainFiles": [
"static/chunks/2zjueh7t2vecu.js",
"static/chunks/30wdrt2uam-rs.js",
"static/chunks/0n-zjr76qg7uq.js",
"static/chunks/0iec5q4ack_04.js",
"static/chunks/27jktro2p5rq9.js",
"static/chunks/turbopack-06glzjf65-whj.js"
]
}

View file

@ -0,0 +1,6 @@
var R=require("./chunks/[turbopack]_runtime.js")("425d580d18f26225.js")
R.c("chunks/[turbopack-node]_transforms_postcss_ts_13hmb-_._.js")
R.c("chunks/[root-of-the-server]__1audplt._.js")
R.m("[turbopack-node]/child_process/globals.ts [postcss] (ecmascript)")
R.m("[turbopack-node]/child_process/evaluate.ts/evaluate.js { INNER => \"[turbopack-node]/transforms/postcss.ts { CONFIG => \\\"[project]/postcss.config.js_.loader.mjs [postcss] (ecmascript)\\\" } [postcss] (ecmascript)\", RUNTIME => \"[turbopack-node]/child_process/evaluate.ts [postcss] (ecmascript)\" } [postcss] (ecmascript)")
module.exports=R.m("[turbopack-node]/child_process/evaluate.ts/evaluate.js { INNER => \"[turbopack-node]/transforms/postcss.ts { CONFIG => \\\"[project]/postcss.config.js_.loader.mjs [postcss] (ecmascript)\\\" } [postcss] (ecmascript)\", RUNTIME => \"[turbopack-node]/child_process/evaluate.ts [postcss] (ecmascript)\" } [postcss] (ecmascript)").exports

View file

@ -0,0 +1,5 @@
{
"version": 3,
"sources": [],
"sections": []
}

View file

@ -0,0 +1,233 @@
module.exports = [
"[externals]/path [external] (path, cjs)", ((__turbopack_context__, module, exports) => {
const mod = __turbopack_context__.x("path", () => require("path"));
module.exports = mod;
}),
"[externals]/url [external] (url, cjs)", ((__turbopack_context__, module, exports) => {
const mod = __turbopack_context__.x("url", () => require("url"));
module.exports = mod;
}),
"[externals]/fs [external] (fs, cjs)", ((__turbopack_context__, module, exports) => {
const mod = __turbopack_context__.x("fs", () => require("fs"));
module.exports = mod;
}),
"[externals]/node:url [external] (node:url, cjs)", ((__turbopack_context__, module, exports) => {
const mod = __turbopack_context__.x("node:url", () => require("node:url"));
module.exports = mod;
}),
"[externals]/node:path [external] (node:path, cjs)", ((__turbopack_context__, module, exports) => {
const mod = __turbopack_context__.x("node:path", () => require("node:path"));
module.exports = mod;
}),
"[project]/postcss.config.js_.loader.mjs [postcss] (ecmascript)", ((__turbopack_context__) => {
"use strict";
return __turbopack_context__.a(async (__turbopack_handle_async_dependencies__, __turbopack_async_result__) => { try {
__turbopack_context__.s([
"default",
()=>__TURBOPACK__default__export__
]);
var __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$url__$5b$external$5d$__$28$node$3a$url$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/node:url [external] (node:url, cjs)");
var __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$path__$5b$external$5d$__$28$node$3a$path$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/node:path [external] (node:path, cjs)");
;
;
const configPath = __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$path__$5b$external$5d$__$28$node$3a$path$2c$__cjs$29$__["default"].join(process.cwd(), "./postcss.config.js");
// Absolute paths don't work with ESM imports on Windows:
// https://github.com/nodejs/node/issues/31710
// convert it to a file:// URL, which works on all platforms
const configUrl = (0, __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$url__$5b$external$5d$__$28$node$3a$url$2c$__cjs$29$__["pathToFileURL"])(configPath).toString();
const mod = await __turbopack_context__.y(configUrl);
const __TURBOPACK__default__export__ = mod.default ?? mod;
__turbopack_async_result__();
} catch(e) { __turbopack_async_result__(e); } }, true);}),
"[turbopack-node]/transforms/transforms.ts [postcss] (ecmascript)", ((__turbopack_context__) => {
"use strict";
/**
* Shared utilities for our 2 transform implementations.
*/ __turbopack_context__.s([
"fromPath",
()=>fromPath,
"getReadEnvVariables",
()=>getReadEnvVariables,
"toPath",
()=>toPath
]);
var __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/path [external] (path, cjs)");
;
const contextDir = process.cwd();
const toPath = (file)=>{
const relPath = (0, __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["relative"])(contextDir, file);
if ((0, __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["isAbsolute"])(relPath)) {
throw new Error(`Cannot depend on path (${file}) outside of root directory (${contextDir})`);
}
return __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["sep"] !== '/' ? relPath.replaceAll(__TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["sep"], '/') : relPath;
};
const fromPath = (path)=>{
return (0, __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["join"])(/* turbopackIgnore: true */ contextDir, __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["sep"] !== '/' ? path.replaceAll('/', __TURBOPACK__imported__module__$5b$externals$5d2f$path__$5b$external$5d$__$28$path$2c$__cjs$29$__["sep"]) : path);
};
// Patch process.env to track which env vars are read
const originalEnv = process.env;
const readEnvVars = new Set();
process.env = new Proxy(originalEnv, {
get (target, prop) {
if (typeof prop === 'string') {
// We register the env var as dependency on the
// current transform and all future transforms
// since the env var might be cached in module scope
// and influence them all
readEnvVars.add(prop);
}
return Reflect.get(target, prop);
},
set (target, prop, value) {
return Reflect.set(target, prop, value);
}
});
function getReadEnvVariables() {
return Array.from(readEnvVars);
}
}),
"[turbopack-node]/transforms/postcss.ts { CONFIG => \"[project]/postcss.config.js_.loader.mjs [postcss] (ecmascript)\" } [postcss] (ecmascript)", ((__turbopack_context__) => {
"use strict";
return __turbopack_context__.a(async (__turbopack_handle_async_dependencies__, __turbopack_async_result__) => { try {
__turbopack_context__.s([
"default",
()=>transform,
"init",
()=>init
]);
// @ts-ignore
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$postcss$2f$lib$2f$postcss$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/postcss/lib/postcss.mjs [postcss] (ecmascript)");
// @ts-ignore
var __TURBOPACK__imported__module__$5b$project$5d2f$postcss$2e$config$2e$js_$2e$loader$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/postcss.config.js_.loader.mjs [postcss] (ecmascript)");
var __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[turbopack-node]/transforms/transforms.ts [postcss] (ecmascript)");
var __turbopack_async_dependencies__ = __turbopack_handle_async_dependencies__([
__TURBOPACK__imported__module__$5b$project$5d2f$postcss$2e$config$2e$js_$2e$loader$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__
]);
[__TURBOPACK__imported__module__$5b$project$5d2f$postcss$2e$config$2e$js_$2e$loader$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__] = __turbopack_async_dependencies__.then ? (await __turbopack_async_dependencies__)() : __turbopack_async_dependencies__;
;
;
;
let processor;
const init = async (ipc)=>{
let config = __TURBOPACK__imported__module__$5b$project$5d2f$postcss$2e$config$2e$js_$2e$loader$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__["default"];
if (typeof config === 'function') {
config = await config({
env: 'development'
});
}
if (typeof config === 'undefined') {
throw new Error('PostCSS config is undefined (make sure to export an function or object from config file)');
}
let plugins;
if (Array.isArray(config.plugins)) {
plugins = config.plugins.map((plugin)=>{
if (Array.isArray(plugin)) {
return plugin;
} else if (typeof plugin === 'string') {
return [
plugin,
{}
];
} else {
return plugin;
}
});
} else if (typeof config.plugins === 'object') {
plugins = Object.entries(config.plugins).filter(([, options])=>options);
} else {
plugins = [];
}
const loadedPlugins = plugins.map((plugin)=>{
if (Array.isArray(plugin)) {
const [arg, options] = plugin;
let pluginFactory = arg;
if (typeof pluginFactory === 'string') {
pluginFactory = require(/* turbopackIgnore: true */ pluginFactory);
}
if (pluginFactory.default) {
pluginFactory = pluginFactory.default;
}
return pluginFactory(options);
}
return plugin;
});
processor = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$postcss$2f$lib$2f$postcss$2e$mjs__$5b$postcss$5d$__$28$ecmascript$29$__["default"])(loadedPlugins);
};
async function transform(ipc, cssContent, name, sourceMap) {
const { css, map, messages } = await processor.process(cssContent, {
from: name,
to: name,
map: sourceMap ? {
inline: false,
annotation: false
} : undefined
});
const assets = [];
const filePaths = [];
const buildFilePaths = [];
const directories = [];
for (const msg of messages){
switch(msg.type){
case 'asset':
assets.push({
file: msg.file,
content: msg.content,
sourceMap: !sourceMap ? undefined : typeof msg.sourceMap === 'string' ? msg.sourceMap : JSON.stringify(msg.sourceMap)
});
break;
case 'dependency':
case 'missing-dependency':
filePaths.push((0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["toPath"])(msg.file));
break;
case 'build-dependency':
buildFilePaths.push((0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["toPath"])(msg.file));
break;
case 'dir-dependency':
directories.push([
(0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["toPath"])(msg.dir),
msg.glob
]);
break;
case 'context-dependency':
directories.push([
(0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["toPath"])(msg.dir),
'**'
]);
break;
default:
break;
}
}
ipc.sendInfo({
type: 'dependencies',
filePaths,
directories,
buildFilePaths,
envVariables: (0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$transforms$2f$transforms$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["getReadEnvVariables"])()
});
return {
css,
map: sourceMap ? JSON.stringify(map) : undefined,
assets
};
}
__turbopack_async_result__();
} catch(e) { __turbopack_async_result__(e); } }, false);}),
];
//# sourceMappingURL=%5Broot-of-the-server%5D__0x0qtct._.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,500 @@
module.exports = [
"[turbopack-node]/child_process/globals.ts [postcss] (ecmascript)", ((__turbopack_context__, module, exports) => {
// @ts-ignore
process.turbopack = {};
}),
"[externals]/node:net [external] (node:net, cjs)", ((__turbopack_context__, module, exports) => {
const mod = __turbopack_context__.x("node:net", () => require("node:net"));
module.exports = mod;
}),
"[externals]/node:stream [external] (node:stream, cjs)", ((__turbopack_context__, module, exports) => {
const mod = __turbopack_context__.x("node:stream", () => require("node:stream"));
module.exports = mod;
}),
"[turbopack-node]/compiled/stacktrace-parser/index.js [postcss] (ecmascript)", ((__turbopack_context__) => {
"use strict";
__turbopack_context__.s([
"parse",
()=>parse
]);
if (typeof __nccwpck_require__ !== "undefined") __nccwpck_require__.ab = ("TURBOPACK compile-time value", "/ROOT/compiled/stacktrace-parser") + "/";
var n = "<unknown>";
function parse(e) {
var r = e.split("\n");
return r.reduce(function(e, r) {
var n = parseChrome(r) || parseWinjs(r) || parseGecko(r) || parseNode(r) || parseJSC(r);
if (n) {
e.push(n);
}
return e;
}, []);
}
var a = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
var l = /\((\S*)(?::(\d+))(?::(\d+))\)/;
function parseChrome(e) {
var r = a.exec(e);
if (!r) {
return null;
}
var u = r[2] && r[2].indexOf("native") === 0;
var t = r[2] && r[2].indexOf("eval") === 0;
var i = l.exec(r[2]);
if (t && i != null) {
r[2] = i[1];
r[3] = i[2];
r[4] = i[3];
}
return {
file: !u ? r[2] : null,
methodName: r[1] || n,
arguments: u ? [
r[2]
] : [],
lineNumber: r[3] ? +r[3] : null,
column: r[4] ? +r[4] : null
};
}
var u = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
function parseWinjs(e) {
var r = u.exec(e);
if (!r) {
return null;
}
return {
file: r[2],
methodName: r[1] || n,
arguments: [],
lineNumber: +r[3],
column: r[4] ? +r[4] : null
};
}
var t = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i;
var i = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
function parseGecko(e) {
var r = t.exec(e);
if (!r) {
return null;
}
var a = r[3] && r[3].indexOf(" > eval") > -1;
var l = i.exec(r[3]);
if (a && l != null) {
r[3] = l[1];
r[4] = l[2];
r[5] = null;
}
return {
file: r[3],
methodName: r[1] || n,
arguments: r[2] ? r[2].split(",") : [],
lineNumber: r[4] ? +r[4] : null,
column: r[5] ? +r[5] : null
};
}
var s = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
function parseJSC(e) {
var r = s.exec(e);
if (!r) {
return null;
}
return {
file: r[3],
methodName: r[1] || n,
arguments: [],
lineNumber: +r[4],
column: r[5] ? +r[5] : null
};
}
var o = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
function parseNode(e) {
var r = o.exec(e);
if (!r) {
return null;
}
return {
file: r[2],
methodName: r[1] || n,
arguments: [],
lineNumber: +r[3],
column: r[4] ? +r[4] : null
};
}
}),
"[turbopack-node]/error.ts [postcss] (ecmascript)", ((__turbopack_context__) => {
"use strict";
__turbopack_context__.s([
"default",
()=>isError,
"getProperError",
()=>getProperError,
"structuredError",
()=>structuredError
]);
var __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$compiled$2f$stacktrace$2d$parser$2f$index$2e$js__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[turbopack-node]/compiled/stacktrace-parser/index.js [postcss] (ecmascript)");
;
function isError(err) {
return typeof err === 'object' && err !== null && 'name' in err && 'message' in err;
}
function getProperError(err) {
if (isError(err)) {
return err;
}
if ("TURBOPACK compile-time falsy", 0) //TURBOPACK unreachable
;
return new Error(isPlainObject(err) ? JSON.stringify(err) : err + '');
}
function getObjectClassLabel(value) {
return Object.prototype.toString.call(value);
}
function isPlainObject(value) {
if (getObjectClassLabel(value) !== '[object Object]') {
return false;
}
const prototype = Object.getPrototypeOf(value);
/**
* this used to be previously:
*
* `return prototype === null || prototype === Object.prototype`
*
* but Edge Runtime expose Object from vm, being that kind of type-checking wrongly fail.
*
* It was changed to the current implementation since it's resilient to serialization.
*/ return prototype === null || prototype.hasOwnProperty('isPrototypeOf');
}
function structuredError(e) {
e = getProperError(e);
return {
name: e.name,
message: e.message,
stack: typeof e.stack === 'string' ? (0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$compiled$2f$stacktrace$2d$parser$2f$index$2e$js__$5b$postcss$5d$__$28$ecmascript$29$__["parse"])(e.stack) : [],
cause: e.cause ? structuredError(getProperError(e.cause)) : undefined
};
}
}),
"[turbopack-node]/child_process/index.ts [postcss] (ecmascript)", ((__turbopack_context__) => {
"use strict";
__turbopack_context__.s([
"IPC",
()=>IPC
]);
var __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$net__$5b$external$5d$__$28$node$3a$net$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/node:net [external] (node:net, cjs)");
var __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$stream__$5b$external$5d$__$28$node$3a$stream$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/node:stream [external] (node:stream, cjs)");
var __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$error$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[turbopack-node]/error.ts [postcss] (ecmascript)");
;
;
;
function createIpc(port) {
const socket = (0, __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$net__$5b$external$5d$__$28$node$3a$net$2c$__cjs$29$__["createConnection"])({
port,
host: '127.0.0.1'
});
/**
* A writable stream that writes to the socket.
* We don't write directly to the socket because we need to
* handle backpressure and wait for the socket to be drained
* before writing more data.
*/ const socketWritable = new __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$stream__$5b$external$5d$__$28$node$3a$stream$2c$__cjs$29$__["Writable"]({
write (chunk, _enc, cb) {
if (socket.write(chunk)) {
cb();
} else {
socket.once('drain', cb);
}
},
final (cb) {
socket.end(cb);
}
});
const packetQueue = [];
const recvPromiseResolveQueue = [];
function pushPacket(packet) {
const recvPromiseResolve = recvPromiseResolveQueue.shift();
if (recvPromiseResolve != null) {
recvPromiseResolve(JSON.parse(packet.toString('utf8')));
} else {
packetQueue.push(packet);
}
}
let state = {
type: 'waiting'
};
let buffer = Buffer.alloc(0);
socket.once('connect', ()=>{
socket.setNoDelay(true);
socket.on('data', (chunk)=>{
buffer = Buffer.concat([
buffer,
chunk
]);
loop: while(true){
switch(state.type){
case 'waiting':
{
if (buffer.length >= 4) {
const length = buffer.readUInt32BE(0);
buffer = buffer.subarray(4);
state = {
type: 'packet',
length
};
} else {
break loop;
}
break;
}
case 'packet':
{
if (buffer.length >= state.length) {
const packet = buffer.subarray(0, state.length);
buffer = buffer.subarray(state.length);
state = {
type: 'waiting'
};
pushPacket(packet);
} else {
break loop;
}
break;
}
default:
invariant(state, (state)=>`Unknown state type: ${state?.type}`);
}
}
});
});
// When the socket is closed, this process is no longer needed.
// This might happen e. g. when parent process is killed or
// node.js pool is garbage collected.
socket.once('close', ()=>{
process.exit(0);
});
// TODO(lukesandberg): some of the messages being sent are very large and contain lots
// of redundant information. Consider adding gzip compression to our stream.
function doSend(message) {
return new Promise((resolve, reject)=>{
// Reserve 4 bytes for our length prefix, we will over-write after encoding.
const packet = Buffer.from('0000' + message, 'utf8');
packet.writeUInt32BE(packet.length - 4, 0);
socketWritable.write(packet, (err)=>{
process.stderr.write(`TURBOPACK_OUTPUT_D\n`);
process.stdout.write(`TURBOPACK_OUTPUT_D\n`);
if (err != null) {
reject(err);
} else {
resolve();
}
});
});
}
function send(message) {
return doSend(JSON.stringify(message));
}
function sendReady() {
return doSend('');
}
return {
async recv () {
const packet = packetQueue.shift();
if (packet != null) {
return JSON.parse(packet.toString('utf8'));
}
const result = await new Promise((resolve)=>{
recvPromiseResolveQueue.push((result)=>{
resolve(result);
});
});
return result;
},
send (message) {
return send(message);
},
sendReady,
async sendError (error) {
let failed = false;
try {
await send({
type: 'error',
...(0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$error$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["structuredError"])(error)
});
} catch (err) {
// There's nothing we can do about errors that happen after this point, we can't tell anyone
// about them.
console.error('failed to send error back to rust:', err);
failed = true;
}
await new Promise((res)=>socket.end(()=>res()));
process.exit(failed ? 1 : 0);
}
};
}
const PORT = process.argv[2];
const IPC = createIpc(parseInt(PORT, 10));
process.on('uncaughtException', (err)=>{
IPC.sendError(err);
});
process.on('unhandledRejection', (reason)=>{
IPC.sendError(reason instanceof Error ? reason : new Error(String(reason)));
});
const improveConsole = (name, stream, addStack)=>{
// @ts-ignore
const original = console[name];
// @ts-ignore
const stdio = process[stream];
// @ts-ignore
console[name] = (...args)=>{
stdio.write(`TURBOPACK_OUTPUT_B\n`);
original(...args);
if (addStack) {
const stack = new Error().stack?.replace(/^.+\n.+\n/, '') + '\n';
stdio.write('TURBOPACK_OUTPUT_S\n');
stdio.write(stack);
}
stdio.write('TURBOPACK_OUTPUT_E\n');
};
};
improveConsole('error', 'stderr', true);
improveConsole('warn', 'stderr', true);
improveConsole('count', 'stdout', true);
improveConsole('trace', 'stderr', false);
improveConsole('log', 'stdout', true);
improveConsole('group', 'stdout', true);
improveConsole('groupCollapsed', 'stdout', true);
improveConsole('table', 'stdout', true);
improveConsole('debug', 'stdout', true);
improveConsole('info', 'stdout', true);
improveConsole('dir', 'stdout', true);
improveConsole('dirxml', 'stdout', true);
improveConsole('timeEnd', 'stdout', true);
improveConsole('timeLog', 'stdout', true);
improveConsole('timeStamp', 'stdout', true);
improveConsole('assert', 'stderr', true);
/**
* Utility function to ensure all variants of an enum are handled.
*/ function invariant(never, computeMessage) {
throw new Error(`Invariant: ${computeMessage(never)}`);
}
}),
"[turbopack-node]/child_process/evaluate.ts [postcss] (ecmascript)", ((__turbopack_context__) => {
"use strict";
__turbopack_context__.s([
"run",
()=>run
]);
var __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$child_process$2f$index$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[turbopack-node]/child_process/index.ts [postcss] (ecmascript)");
;
const ipc = __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$child_process$2f$index$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["IPC"];
const queue = [];
const run = async (moduleFactory)=>{
let nextId = 1;
const requests = new Map();
const internalIpc = {
sendInfo: (message)=>ipc.send({
type: 'info',
data: message
}),
sendRequest: (message)=>{
const id = nextId++;
let resolve, reject;
const promise = new Promise((res, rej)=>{
resolve = res;
reject = rej;
});
requests.set(id, {
resolve,
reject
});
return ipc.send({
type: 'request',
id,
data: message
}).then(()=>promise);
},
sendError: (error)=>{
return ipc.sendError(error);
}
};
// Initialize module and send ready message
let getValue;
try {
const module = await moduleFactory();
if (typeof module.init === 'function') {
await module.init();
}
getValue = module.default;
await ipc.sendReady();
} catch (err) {
await ipc.sendReady();
await ipc.sendError(err);
}
// Queue handling
let isRunning = false;
const run = async ()=>{
while(queue.length > 0){
const args = queue.shift();
try {
const value = await getValue(internalIpc, ...args);
await ipc.send({
type: 'end',
data: value === undefined ? undefined : JSON.stringify(value, null, 2),
duration: 0
});
} catch (e) {
await ipc.sendError(e);
}
}
isRunning = false;
};
// Communication handling
while(true){
const msg = await ipc.recv();
switch(msg.type){
case 'evaluate':
{
queue.push(msg.args);
if (!isRunning) {
isRunning = true;
run();
}
break;
}
case 'result':
{
const request = requests.get(msg.id);
if (request) {
requests.delete(msg.id);
if (msg.error) {
request.reject(new Error(msg.error));
} else {
request.resolve(msg.data);
}
}
break;
}
default:
{
console.error('unexpected message type', msg.type);
process.exit(1);
}
}
}
};
}),
"[turbopack-node]/child_process/evaluate.ts/evaluate.js { INNER => \"[turbopack-node]/transforms/postcss.ts { CONFIG => \\\"[project]/postcss.config.js_.loader.mjs [postcss] (ecmascript)\\\" } [postcss] (ecmascript)\", RUNTIME => \"[turbopack-node]/child_process/evaluate.ts [postcss] (ecmascript)\" } [postcss] (ecmascript)", ((__turbopack_context__) => {
"use strict";
__turbopack_context__.s([]);
var __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$child_process$2f$evaluate$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[turbopack-node]/child_process/evaluate.ts [postcss] (ecmascript)");
;
(0, __TURBOPACK__imported__module__$5b$turbopack$2d$node$5d2f$child_process$2f$evaluate$2e$ts__$5b$postcss$5d$__$28$ecmascript$29$__["run"])(()=>__turbopack_context__.A('[turbopack-node]/transforms/postcss.ts { CONFIG => "[project]/postcss.config.js_.loader.mjs [postcss] (ecmascript)" } [postcss] (ecmascript, async loader)'));
}),
];
//# sourceMappingURL=%5Broot-of-the-server%5D__1audplt._.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,13 @@
module.exports = [
"[turbopack-node]/transforms/postcss.ts { CONFIG => \"[project]/postcss.config.js_.loader.mjs [postcss] (ecmascript)\" } [postcss] (ecmascript, async loader)", ((__turbopack_context__) => {
__turbopack_context__.v((parentImport) => {
return Promise.all([
"chunks/node_modules_20v-8wl._.js",
"chunks/[root-of-the-server]__0x0qtct._.js"
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
return parentImport("[turbopack-node]/transforms/postcss.ts { CONFIG => \"[project]/postcss.config.js_.loader.mjs [postcss] (ecmascript)\" } [postcss] (ecmascript)");
});
});
}),
];

View file

@ -0,0 +1,5 @@
{
"version": 3,
"sources": [],
"sections": []
}

View file

@ -0,0 +1,890 @@
const RUNTIME_PUBLIC_PATH = "chunks/[turbopack]_runtime.js";
const RELATIVE_ROOT_PATH = "..";
const ASSET_PREFIX = "/";
const WORKER_FORWARDED_GLOBALS = [];
/**
* This file contains runtime types and functions that are shared between all
* TurboPack ECMAScript runtimes.
*
* It will be prepended to the runtime code of each runtime.
*/ /* eslint-disable @typescript-eslint/no-unused-vars */ /// <reference path="./runtime-types.d.ts" />
/**
* Describes why a module was instantiated.
* Shared between browser and Node.js runtimes.
*/ var SourceType = /*#__PURE__*/ function(SourceType) {
/**
* The module was instantiated because it was included in an evaluated chunk's
* runtime.
* SourceData is a ChunkPath.
*/ SourceType[SourceType["Runtime"] = 0] = "Runtime";
/**
* The module was instantiated because a parent module imported it.
* SourceData is a ModuleId.
*/ SourceType[SourceType["Parent"] = 1] = "Parent";
/**
* The module was instantiated because it was included in a chunk's hot module
* update.
* SourceData is an array of ModuleIds or undefined.
*/ SourceType[SourceType["Update"] = 2] = "Update";
return SourceType;
}(SourceType || {});
/**
* Flag indicating which module object type to create when a module is merged. Set to `true`
* by each runtime that uses ModuleWithDirection (browser dev-base.ts, nodejs dev-base.ts,
* nodejs build-base.ts). Browser production (build-base.ts) leaves it as `false` since it
* uses plain Module objects.
*/ let createModuleWithDirectionFlag = false;
const REEXPORTED_OBJECTS = new WeakMap();
/**
* Constructs the `__turbopack_context__` object for a module.
*/ function Context(module, exports) {
this.m = module;
// We need to store this here instead of accessing it from the module object to:
// 1. Make it available to factories directly, since we rewrite `this` to
// `__turbopack_context__.e` in CJS modules.
// 2. Support async modules which rewrite `module.exports` to a promise, so we
// can still access the original exports object from functions like
// `esmExport`
// Ideally we could find a new approach for async modules and drop this property altogether.
this.e = exports;
}
const contextPrototype = Context.prototype;
const hasOwnProperty = Object.prototype.hasOwnProperty;
const toStringTag = typeof Symbol !== 'undefined' && Symbol.toStringTag;
function defineProp(obj, name, options) {
if (!hasOwnProperty.call(obj, name)) Object.defineProperty(obj, name, options);
}
function getOverwrittenModule(moduleCache, id) {
let module = moduleCache[id];
if (!module) {
if (createModuleWithDirectionFlag) {
// set in development modes for hmr support
module = createModuleWithDirection(id);
} else {
module = createModuleObject(id);
}
moduleCache[id] = module;
}
return module;
}
/**
* Creates the module object. Only done here to ensure all module objects have the same shape.
*/ function createModuleObject(id) {
return {
exports: {},
error: undefined,
id,
namespaceObject: undefined
};
}
function createModuleWithDirection(id) {
return {
exports: {},
error: undefined,
id,
namespaceObject: undefined,
parents: [],
children: []
};
}
const BindingTag_Value = 0;
/**
* Adds the getters to the exports object.
*/ function esm(exports, bindings) {
defineProp(exports, '__esModule', {
value: true
});
if (toStringTag) defineProp(exports, toStringTag, {
value: 'Module'
});
let i = 0;
while(i < bindings.length){
const propName = bindings[i++];
const tagOrFunction = bindings[i++];
if (typeof tagOrFunction === 'number') {
if (tagOrFunction === BindingTag_Value) {
defineProp(exports, propName, {
value: bindings[i++],
enumerable: true,
writable: false
});
} else {
throw new Error(`unexpected tag: ${tagOrFunction}`);
}
} else {
const getterFn = tagOrFunction;
if (typeof bindings[i] === 'function') {
const setterFn = bindings[i++];
defineProp(exports, propName, {
get: getterFn,
set: setterFn,
enumerable: true
});
} else {
defineProp(exports, propName, {
get: getterFn,
enumerable: true
});
}
}
}
Object.seal(exports);
}
/**
* Makes the module an ESM with exports
*/ function esmExport(bindings, id) {
let module;
let exports;
if (id != null) {
module = getOverwrittenModule(this.c, id);
exports = module.exports;
} else {
module = this.m;
exports = this.e;
}
module.namespaceObject = exports;
esm(exports, bindings);
}
contextPrototype.s = esmExport;
function ensureDynamicExports(module, exports) {
let reexportedObjects = REEXPORTED_OBJECTS.get(module);
if (!reexportedObjects) {
REEXPORTED_OBJECTS.set(module, reexportedObjects = []);
module.exports = module.namespaceObject = new Proxy(exports, {
get (target, prop) {
if (hasOwnProperty.call(target, prop) || prop === 'default' || prop === '__esModule') {
return Reflect.get(target, prop);
}
for (const obj of reexportedObjects){
const value = Reflect.get(obj, prop);
if (value !== undefined) return value;
}
return undefined;
},
ownKeys (target) {
const keys = Reflect.ownKeys(target);
for (const obj of reexportedObjects){
for (const key of Reflect.ownKeys(obj)){
if (key !== 'default' && !keys.includes(key)) keys.push(key);
}
}
return keys;
}
});
}
return reexportedObjects;
}
/**
* Dynamically exports properties from an object
*/ function dynamicExport(object, id) {
let module;
let exports;
if (id != null) {
module = getOverwrittenModule(this.c, id);
exports = module.exports;
} else {
module = this.m;
exports = this.e;
}
const reexportedObjects = ensureDynamicExports(module, exports);
if (typeof object === 'object' && object !== null) {
reexportedObjects.push(object);
}
}
contextPrototype.j = dynamicExport;
function exportValue(value, id) {
let module;
if (id != null) {
module = getOverwrittenModule(this.c, id);
} else {
module = this.m;
}
module.exports = value;
}
contextPrototype.v = exportValue;
function exportNamespace(namespace, id) {
let module;
if (id != null) {
module = getOverwrittenModule(this.c, id);
} else {
module = this.m;
}
module.exports = module.namespaceObject = namespace;
}
contextPrototype.n = exportNamespace;
function createGetter(obj, key) {
return ()=>obj[key];
}
/**
* @returns prototype of the object
*/ const getProto = Object.getPrototypeOf ? (obj)=>Object.getPrototypeOf(obj) : (obj)=>obj.__proto__;
/** Prototypes that are not expanded for exports */ const LEAF_PROTOTYPES = [
null,
getProto({}),
getProto([]),
getProto(getProto)
];
/**
* @param raw
* @param ns
* @param allowExportDefault
* * `false`: will have the raw module as default export
* * `true`: will have the default property as default export
*/ function interopEsm(raw, ns, allowExportDefault) {
const bindings = [];
let defaultLocation = -1;
for(let current = raw; (typeof current === 'object' || typeof current === 'function') && !LEAF_PROTOTYPES.includes(current); current = getProto(current)){
for (const key of Object.getOwnPropertyNames(current)){
bindings.push(key, createGetter(raw, key));
if (defaultLocation === -1 && key === 'default') {
defaultLocation = bindings.length - 1;
}
}
}
// this is not really correct
// we should set the `default` getter if the imported module is a `.cjs file`
if (!(allowExportDefault && defaultLocation >= 0)) {
// Replace the binding with one for the namespace itself in order to preserve iteration order.
if (defaultLocation >= 0) {
// Replace the getter with the value
bindings.splice(defaultLocation, 1, BindingTag_Value, raw);
} else {
bindings.push('default', BindingTag_Value, raw);
}
}
esm(ns, bindings);
return ns;
}
function createNS(raw) {
if (typeof raw === 'function') {
return function(...args) {
return raw.apply(this, args);
};
} else {
return Object.create(null);
}
}
function esmImport(id) {
const module = getOrInstantiateModuleFromParent(id, this.m);
// any ES module has to have `module.namespaceObject` defined.
if (module.namespaceObject) return module.namespaceObject;
// only ESM can be an async module, so we don't need to worry about exports being a promise here.
const raw = module.exports;
return module.namespaceObject = interopEsm(raw, createNS(raw), raw && raw.__esModule);
}
contextPrototype.i = esmImport;
function asyncLoader(moduleId) {
const loader = this.r(moduleId);
return loader(esmImport.bind(this));
}
contextPrototype.A = asyncLoader;
// Add a simple runtime require so that environments without one can still pass
// `typeof require` CommonJS checks so that exports are correctly registered.
const runtimeRequire = // @ts-ignore
typeof require === 'function' ? require : function require1() {
throw new Error('Unexpected use of runtime require');
};
contextPrototype.t = runtimeRequire;
function commonJsRequire(id) {
return getOrInstantiateModuleFromParent(id, this.m).exports;
}
contextPrototype.r = commonJsRequire;
/**
* Remove fragments and query parameters since they are never part of the context map keys
*
* This matches how we parse patterns at resolving time. Arguably we should only do this for
* strings passed to `import` but the resolve does it for `import` and `require` and so we do
* here as well.
*/ function parseRequest(request) {
// Per the URI spec fragments can contain `?` characters, so we should trim it off first
// https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
const hashIndex = request.indexOf('#');
if (hashIndex !== -1) {
request = request.substring(0, hashIndex);
}
const queryIndex = request.indexOf('?');
if (queryIndex !== -1) {
request = request.substring(0, queryIndex);
}
return request;
}
/**
* `require.context` and require/import expression runtime.
*/ function moduleContext(map) {
function moduleContext(id) {
id = parseRequest(id);
if (hasOwnProperty.call(map, id)) {
return map[id].module();
}
const e = new Error(`Cannot find module '${id}'`);
e.code = 'MODULE_NOT_FOUND';
throw e;
}
moduleContext.keys = ()=>{
return Object.keys(map);
};
moduleContext.resolve = (id)=>{
id = parseRequest(id);
if (hasOwnProperty.call(map, id)) {
return map[id].id();
}
const e = new Error(`Cannot find module '${id}'`);
e.code = 'MODULE_NOT_FOUND';
throw e;
};
moduleContext.import = async (id)=>{
return await moduleContext(id);
};
return moduleContext;
}
contextPrototype.f = moduleContext;
/**
* Returns the path of a chunk defined by its data.
*/ function getChunkPath(chunkData) {
return typeof chunkData === 'string' ? chunkData : chunkData.path;
}
function isPromise(maybePromise) {
return maybePromise != null && typeof maybePromise === 'object' && 'then' in maybePromise && typeof maybePromise.then === 'function';
}
function isAsyncModuleExt(obj) {
return turbopackQueues in obj;
}
function createPromise() {
let resolve;
let reject;
const promise = new Promise((res, rej)=>{
reject = rej;
resolve = res;
});
return {
promise,
resolve: resolve,
reject: reject
};
}
// Load the CompressedmoduleFactories of a chunk into the `moduleFactories` Map.
// The CompressedModuleFactories format is
// - 1 or more module ids
// - a module factory function
// So walking this is a little complex but the flat structure is also fast to
// traverse, we can use `typeof` operators to distinguish the two cases.
function installCompressedModuleFactories(chunkModules, offset, moduleFactories, newModuleId) {
let i = offset;
while(i < chunkModules.length){
let end = i + 1;
// Find our factory function
while(end < chunkModules.length && typeof chunkModules[end] !== 'function'){
end++;
}
if (end === chunkModules.length) {
throw new Error('malformed chunk format, expected a factory function');
}
// Install the factory for each module ID that doesn't already have one.
// When some IDs in this group already have a factory, reuse that existing
// group factory for the missing IDs to keep all IDs in the group consistent.
// Otherwise, install the factory from this chunk.
const moduleFactoryFn = chunkModules[end];
let existingGroupFactory = undefined;
for(let j = i; j < end; j++){
const id = chunkModules[j];
const existingFactory = moduleFactories.get(id);
if (existingFactory) {
existingGroupFactory = existingFactory;
break;
}
}
const factoryToInstall = existingGroupFactory ?? moduleFactoryFn;
let didInstallFactory = false;
for(let j = i; j < end; j++){
const id = chunkModules[j];
if (!moduleFactories.has(id)) {
if (!didInstallFactory) {
if (factoryToInstall === moduleFactoryFn) {
applyModuleFactoryName(moduleFactoryFn);
}
didInstallFactory = true;
}
moduleFactories.set(id, factoryToInstall);
newModuleId?.(id);
}
}
i = end + 1; // end is pointing at the last factory advance to the next id or the end of the array.
}
}
// everything below is adapted from webpack
// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13
const turbopackQueues = Symbol('turbopack queues');
const turbopackExports = Symbol('turbopack exports');
const turbopackError = Symbol('turbopack error');
function resolveQueue(queue) {
if (queue && queue.status !== 1) {
queue.status = 1;
queue.forEach((fn)=>fn.queueCount--);
queue.forEach((fn)=>fn.queueCount-- ? fn.queueCount++ : fn());
}
}
function wrapDeps(deps) {
return deps.map((dep)=>{
if (dep !== null && typeof dep === 'object') {
if (isAsyncModuleExt(dep)) return dep;
if (isPromise(dep)) {
const queue = Object.assign([], {
status: 0
});
const obj = {
[turbopackExports]: {},
[turbopackQueues]: (fn)=>fn(queue)
};
dep.then((res)=>{
obj[turbopackExports] = res;
resolveQueue(queue);
}, (err)=>{
obj[turbopackError] = err;
resolveQueue(queue);
});
return obj;
}
}
return {
[turbopackExports]: dep,
[turbopackQueues]: ()=>{}
};
});
}
function asyncModule(body, hasAwait) {
const module = this.m;
const queue = hasAwait ? Object.assign([], {
status: -1
}) : undefined;
const depQueues = new Set();
const { resolve, reject, promise: rawPromise } = createPromise();
const promise = Object.assign(rawPromise, {
[turbopackExports]: module.exports,
[turbopackQueues]: (fn)=>{
queue && fn(queue);
depQueues.forEach(fn);
promise['catch'](()=>{});
}
});
const attributes = {
get () {
return promise;
},
set (v) {
// Calling `esmExport` leads to this.
if (v !== promise) {
promise[turbopackExports] = v;
}
}
};
Object.defineProperty(module, 'exports', attributes);
Object.defineProperty(module, 'namespaceObject', attributes);
function handleAsyncDependencies(deps) {
const currentDeps = wrapDeps(deps);
const getResult = ()=>currentDeps.map((d)=>{
if (d[turbopackError]) throw d[turbopackError];
return d[turbopackExports];
});
const { promise, resolve } = createPromise();
const fn = Object.assign(()=>resolve(getResult), {
queueCount: 0
});
function fnQueue(q) {
if (q !== queue && !depQueues.has(q)) {
depQueues.add(q);
if (q && q.status === 0) {
fn.queueCount++;
q.push(fn);
}
}
}
currentDeps.map((dep)=>dep[turbopackQueues](fnQueue));
return fn.queueCount ? promise : getResult();
}
function asyncResult(err) {
if (err) {
reject(promise[turbopackError] = err);
} else {
resolve(promise[turbopackExports]);
}
resolveQueue(queue);
}
body(handleAsyncDependencies, asyncResult);
if (queue && queue.status === -1) {
queue.status = 0;
}
}
contextPrototype.a = asyncModule;
/**
* A pseudo "fake" URL object to resolve to its relative path.
*
* When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this
* runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid
* hydration mismatch.
*
* This is based on webpack's existing implementation:
* https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js
*/ const relativeURL = function relativeURL(inputUrl) {
const realUrl = new URL(inputUrl, 'x:/');
const values = {};
for(const key in realUrl)values[key] = realUrl[key];
values.href = inputUrl;
values.pathname = inputUrl.replace(/[?#].*/, '');
values.origin = values.protocol = '';
values.toString = values.toJSON = (..._args)=>inputUrl;
for(const key in values)Object.defineProperty(this, key, {
enumerable: true,
configurable: true,
value: values[key]
});
};
relativeURL.prototype = URL.prototype;
contextPrototype.U = relativeURL;
/**
* Utility function to ensure all variants of an enum are handled.
*/ function invariant(never, computeMessage) {
throw new Error(`Invariant: ${computeMessage(never)}`);
}
/**
* Constructs an error message for when a module factory is not available.
*/ function factoryNotAvailableMessage(moduleId, sourceType, sourceData) {
let instantiationReason;
switch(sourceType){
case 0:
instantiationReason = `as a runtime entry of chunk ${sourceData}`;
break;
case 1:
instantiationReason = `because it was required from module ${sourceData}`;
break;
case 2:
instantiationReason = 'because of an HMR update';
break;
default:
invariant(sourceType, (sourceType)=>`Unknown source type: ${sourceType}`);
}
return `Module ${moduleId} was instantiated ${instantiationReason}, but the module factory is not available.`;
}
/**
* A stub function to make `require` available but non-functional in ESM.
*/ function requireStub(_moduleId) {
throw new Error('dynamic usage of require is not supported');
}
contextPrototype.z = requireStub;
// Make `globalThis` available to the module in a way that cannot be shadowed by a local variable.
contextPrototype.g = globalThis;
function applyModuleFactoryName(factory) {
// Give the module factory a nice name to improve stack traces.
Object.defineProperty(factory, 'name', {
value: 'module evaluation'
});
}
/// <reference path="../shared/runtime/runtime-utils.ts" />
/// A 'base' utilities to support runtime can have externals.
/// Currently this is for node.js / edge runtime both.
/// If a fn requires node.js specific behavior, it should be placed in `node-external-utils` instead.
async function externalImport(id) {
let raw;
try {
raw = await import(id);
} catch (err) {
// TODO(alexkirsz) This can happen when a client-side module tries to load
// an external module we don't provide a shim for (e.g. querystring, url).
// For now, we fail semi-silently, but in the future this should be a
// compilation error.
throw new Error(`Failed to load external module ${id}: ${err}`);
}
if (raw && raw.__esModule && raw.default && 'default' in raw.default) {
return interopEsm(raw.default, createNS(raw), true);
}
return raw;
}
contextPrototype.y = externalImport;
function externalRequire(id, thunk, esm = false) {
let raw;
try {
raw = thunk();
} catch (err) {
// TODO(alexkirsz) This can happen when a client-side module tries to load
// an external module we don't provide a shim for (e.g. querystring, url).
// For now, we fail semi-silently, but in the future this should be a
// compilation error.
throw new Error(`Failed to load external module ${id}: ${err}`);
}
if (!esm || raw.__esModule) {
return raw;
}
return interopEsm(raw, createNS(raw), true);
}
externalRequire.resolve = (id, options)=>{
return require.resolve(id, options);
};
contextPrototype.x = externalRequire;
/* eslint-disable @typescript-eslint/no-unused-vars */ const path = require('path');
const relativePathToRuntimeRoot = path.relative(RUNTIME_PUBLIC_PATH, '.');
// Compute the relative path to the `distDir`.
const relativePathToDistRoot = path.join(relativePathToRuntimeRoot, RELATIVE_ROOT_PATH);
const RUNTIME_ROOT = path.resolve(__filename, relativePathToRuntimeRoot);
// Compute the absolute path to the root, by stripping distDir from the absolute path to this file.
const ABSOLUTE_ROOT = path.resolve(__filename, relativePathToDistRoot);
/**
* Returns an absolute path to the given module path.
* Module path should be relative, either path to a file or a directory.
*
* This fn allows to calculate an absolute path for some global static values, such as
* `__dirname` or `import.meta.url` that Turbopack will not embeds in compile time.
* See ImportMetaBinding::code_generation for the usage.
*/ function resolveAbsolutePath(modulePath) {
if (modulePath) {
return path.join(ABSOLUTE_ROOT, modulePath);
}
return ABSOLUTE_ROOT;
}
Context.prototype.P = resolveAbsolutePath;
/* eslint-disable @typescript-eslint/no-unused-vars */ /// <reference path="../shared/runtime/runtime-utils.ts" />
function readWebAssemblyAsResponse(path) {
const { createReadStream } = require('fs');
const { Readable } = require('stream');
const stream = createReadStream(path);
// @ts-ignore unfortunately there's a slight type mismatch with the stream.
return new Response(Readable.toWeb(stream), {
headers: {
'content-type': 'application/wasm'
}
});
}
async function compileWebAssemblyFromPath(path) {
const response = readWebAssemblyAsResponse(path);
return await WebAssembly.compileStreaming(response);
}
async function instantiateWebAssemblyFromPath(path, importsObj) {
const response = readWebAssemblyAsResponse(path);
const { instance } = await WebAssembly.instantiateStreaming(response, importsObj);
return instance.exports;
}
/* eslint-disable @typescript-eslint/no-unused-vars */ /// <reference path="../../shared/runtime/runtime-utils.ts" />
/// <reference path="../../shared-node/base-externals-utils.ts" />
/// <reference path="../../shared-node/node-externals-utils.ts" />
/// <reference path="../../shared-node/node-wasm-utils.ts" />
/// <reference path="./nodejs-globals.d.ts" />
/**
* Base Node.js runtime shared between production and development.
* Contains chunk loading, module caching, and other non-HMR functionality.
*/ process.env.TURBOPACK = '1';
const url = require('url');
const moduleFactories = new Map();
const moduleCache = Object.create(null);
/**
* Returns an absolute path to the given module's id.
*/ function resolvePathFromModule(moduleId) {
const exported = this.r(moduleId);
const exportedPath = exported?.default ?? exported;
if (typeof exportedPath !== 'string') {
return exported;
}
const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length);
const resolved = path.resolve(RUNTIME_ROOT, strippedAssetPrefix);
return url.pathToFileURL(resolved).href;
}
/**
* Exports a URL value. No suffix is added in Node.js runtime.
*/ function exportUrl(urlValue, id) {
exportValue.call(this, urlValue, id);
}
function loadRuntimeChunk(sourcePath, chunkData) {
if (typeof chunkData === 'string') {
loadRuntimeChunkPath(sourcePath, chunkData);
} else {
loadRuntimeChunkPath(sourcePath, chunkData.path);
}
}
const loadedChunks = new Set();
const unsupportedLoadChunk = Promise.resolve(undefined);
const loadedChunk = Promise.resolve(undefined);
const chunkCache = new Map();
function clearChunkCache() {
chunkCache.clear();
loadedChunks.clear();
}
function loadRuntimeChunkPath(sourcePath, chunkPath) {
if (!isJs(chunkPath)) {
// We only support loading JS chunks in Node.js.
// This branch can be hit when trying to load a CSS chunk.
return;
}
if (loadedChunks.has(chunkPath)) {
return;
}
try {
const resolved = path.resolve(RUNTIME_ROOT, chunkPath);
const chunkModules = require(resolved);
installCompressedModuleFactories(chunkModules, 0, moduleFactories);
loadedChunks.add(chunkPath);
} catch (cause) {
let errorMessage = `Failed to load chunk ${chunkPath}`;
if (sourcePath) {
errorMessage += ` from runtime for chunk ${sourcePath}`;
}
const error = new Error(errorMessage, {
cause
});
error.name = 'ChunkLoadError';
throw error;
}
}
function loadChunkAsync(chunkData) {
const chunkPath = typeof chunkData === 'string' ? chunkData : chunkData.path;
if (!isJs(chunkPath)) {
// We only support loading JS chunks in Node.js.
// This branch can be hit when trying to load a CSS chunk.
return unsupportedLoadChunk;
}
let entry = chunkCache.get(chunkPath);
if (entry === undefined) {
try {
// resolve to an absolute path to simplify `require` handling
const resolved = path.resolve(RUNTIME_ROOT, chunkPath);
// TODO: consider switching to `import()` to enable concurrent chunk loading and async file io
// However this is incompatible with hot reloading (since `import` doesn't use the require cache)
const chunkModules = require(resolved);
installCompressedModuleFactories(chunkModules, 0, moduleFactories);
entry = loadedChunk;
} catch (cause) {
const errorMessage = `Failed to load chunk ${chunkPath} from module ${this.m.id}`;
const error = new Error(errorMessage, {
cause
});
error.name = 'ChunkLoadError';
// Cache the failure promise, future requests will also get this same rejection
entry = Promise.reject(error);
}
chunkCache.set(chunkPath, entry);
}
// TODO: Return an instrumented Promise that React can use instead of relying on referential equality.
return entry;
}
contextPrototype.l = loadChunkAsync;
function loadChunkAsyncByUrl(chunkUrl) {
const path1 = url.fileURLToPath(new URL(chunkUrl, RUNTIME_ROOT));
return loadChunkAsync.call(this, path1);
}
contextPrototype.L = loadChunkAsyncByUrl;
function loadWebAssembly(chunkPath, _edgeModule, imports) {
const resolved = path.resolve(RUNTIME_ROOT, chunkPath);
return instantiateWebAssemblyFromPath(resolved, imports);
}
contextPrototype.w = loadWebAssembly;
function loadWebAssemblyModule(chunkPath, _edgeModule) {
const resolved = path.resolve(RUNTIME_ROOT, chunkPath);
return compileWebAssemblyFromPath(resolved);
}
contextPrototype.u = loadWebAssemblyModule;
/**
* Creates a Node.js worker thread by instantiating the given WorkerConstructor
* with the appropriate path and options, including forwarded globals.
*
* @param WorkerConstructor The Worker constructor from worker_threads
* @param workerPath Path to the worker entry chunk
* @param workerOptions options to pass to the Worker constructor (optional)
*/ function createWorker(WorkerConstructor, workerPath, workerOptions) {
// Build the forwarded globals object
const forwardedGlobals = {};
for (const name of WORKER_FORWARDED_GLOBALS){
forwardedGlobals[name] = globalThis[name];
}
// Merge workerData with forwarded globals
const existingWorkerData = workerOptions?.workerData || {};
const options = {
...workerOptions,
workerData: {
...typeof existingWorkerData === 'object' ? existingWorkerData : {},
__turbopack_globals__: forwardedGlobals
}
};
return new WorkerConstructor(workerPath, options);
}
const regexJsUrl = /\.js(?:\?[^#]*)?(?:#.*)?$/;
/**
* Checks if a given path/URL ends with .js, optionally followed by ?query or #fragment.
*/ function isJs(chunkUrlOrPath) {
return regexJsUrl.test(chunkUrlOrPath);
}
/* eslint-disable @typescript-eslint/no-unused-vars */ /// <reference path="./runtime-base.ts" />
/**
* Production Node.js runtime.
* Uses ModuleWithDirection and simple module instantiation without HMR support.
*/ // moduleCache and moduleFactories are declared in runtime-base.ts
// this is read in runtime-utils.ts so it creates a module with direction for hmr
createModuleWithDirectionFlag = true;
const nodeContextPrototype = Context.prototype;
nodeContextPrototype.q = exportUrl;
nodeContextPrototype.M = moduleFactories;
// Cast moduleCache to ModuleWithDirection for production mode
nodeContextPrototype.c = moduleCache;
nodeContextPrototype.R = resolvePathFromModule;
nodeContextPrototype.b = createWorker;
nodeContextPrototype.C = clearChunkCache;
function instantiateModule(id, sourceType, sourceData) {
const moduleFactory = moduleFactories.get(id);
if (typeof moduleFactory !== 'function') {
// This can happen if modules incorrectly handle HMR disposes/updates,
// e.g. when they keep a `setTimeout` around which still executes old code
// and contains e.g. a `require("something")` call.
throw new Error(factoryNotAvailableMessage(id, sourceType, sourceData));
}
const module1 = createModuleWithDirection(id);
const exports = module1.exports;
moduleCache[id] = module1;
const context = new Context(module1, exports);
// NOTE(alexkirsz) This can fail when the module encounters a runtime error.
try {
moduleFactory(context, module1, exports);
} catch (error) {
module1.error = error;
throw error;
}
;
module1.loaded = true;
if (module1.namespaceObject && module1.exports !== module1.namespaceObject) {
// in case of a circular dependency: cjs1 -> esm2 -> cjs1
interopEsm(module1.exports, module1.namespaceObject);
}
return module1;
}
/**
* Retrieves a module from the cache, or instantiate it if it is not cached.
*/ // @ts-ignore
function getOrInstantiateModuleFromParent(id, sourceModule) {
const module1 = moduleCache[id];
if (module1) {
if (module1.error) {
throw module1.error;
}
return module1;
}
return instantiateModule(id, SourceType.Parent, sourceModule.id);
}
/**
* Instantiates a runtime module.
*/ function instantiateRuntimeModule(chunkPath, moduleId) {
return instantiateModule(moduleId, SourceType.Runtime, chunkPath);
}
/**
* Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached.
*/ // @ts-ignore TypeScript doesn't separate this module space from the browser runtime
function getOrInstantiateRuntimeModule(chunkPath, moduleId) {
const module1 = moduleCache[moduleId];
if (module1) {
if (module1.error) {
throw module1.error;
}
return module1;
}
return instantiateRuntimeModule(chunkPath, moduleId);
}
module.exports = (sourcePath)=>({
m: (id)=>getOrInstantiateRuntimeModule(sourcePath, id),
c: (chunkData)=>loadRuntimeChunk(sourcePath, chunkData)
});
//# sourceMappingURL=%5Bturbopack%5D_runtime.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"type": "commonjs"}

View file

@ -0,0 +1 @@
{"previewModeId":"0f172cc22924763dbc2171b120c8e101","previewModeSigningKey":"edaf77e3d43cb1652a2c42b9827062f602086c8aae104689b67ca3f7f4907b0c","previewModeEncryptionKey":"1a645d1d69a5d15a9c01f8a02a837daa722446dbaa1ad52098685247ffb9188c","expireAt":1784995298786}

View file

@ -0,0 +1 @@
{"encryption.key":"+/et5PtgFqduwH/FIeKKhFN8OgLmX1v88vZt8Z32w3w=","encryption.expire_at":1784995298782}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,6 @@
{
"buildStage": "static-generation",
"buildOptions": {
"useBuildWorker": "true"
}
}

View file

@ -0,0 +1 @@
{"name":"Next.js","version":"16.2.10"}

View file

@ -0,0 +1,313 @@
[
{
"route": "/validations/[id]/edit",
"firstLoadUncompressedJsBytes": 747795,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/2_kp701adm390.js",
".next/static/chunks/3ltfzh6dxauii.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/validations/new",
"firstLoadUncompressedJsBytes": 747627,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/0avs4wxhun5en.js",
".next/static/chunks/3ltfzh6dxauii.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/users",
"firstLoadUncompressedJsBytes": 733546,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/1cqp122st_-zm.js",
".next/static/chunks/3ltfzh6dxauii.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/devices",
"firstLoadUncompressedJsBytes": 729070,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/1m60fm0dtqtgw.js",
".next/static/chunks/1ynnqp1y5f44o.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/equipment",
"firstLoadUncompressedJsBytes": 728433,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/3ssrpy29apyud.js",
".next/static/chunks/1ynnqp1y5f44o.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/customers",
"firstLoadUncompressedJsBytes": 728216,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/0mesgq8f7cu36.js",
".next/static/chunks/1ynnqp1y5f44o.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/contacts",
"firstLoadUncompressedJsBytes": 727881,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/13lr3p114y1co.js",
".next/static/chunks/1ynnqp1y5f44o.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/locations",
"firstLoadUncompressedJsBytes": 727876,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/32d7iq3bhw0do.js",
".next/static/chunks/1ynnqp1y5f44o.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/profile/security",
"firstLoadUncompressedJsBytes": 710615,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/19-dmj7e3s4r_.js",
".next/static/chunks/3ltfzh6dxauii.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/validations",
"firstLoadUncompressedJsBytes": 687563,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/2i7cj1rjfcs5w.js",
".next/static/chunks/2ub3fzreqwyk3.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/login",
"firstLoadUncompressedJsBytes": 672089,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/1lnah75lrauwn.js",
".next/static/chunks/3ltfzh6dxauii.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/validations/quick-start",
"firstLoadUncompressedJsBytes": 633692,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/0_iiecbkgkdlf.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/dashboard",
"firstLoadUncompressedJsBytes": 625974,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/18p5d--rej6cj.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/validations/[id]/preview",
"firstLoadUncompressedJsBytes": 612190,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/3bmssrj1g6gvs.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/documents",
"firstLoadUncompressedJsBytes": 608116,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2ihp5qgm-kkus.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/",
"firstLoadUncompressedJsBytes": 550219,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
},
{
"route": "/_not-found",
"firstLoadUncompressedJsBytes": 550219,
"firstLoadChunkPaths": [
".next/static/chunks/05-c3ty_6dwfk.js",
".next/static/chunks/14mrh2-p_w84d.js",
".next/static/chunks/34jc288cp41wf.js",
".next/static/chunks/3ehzmerq6j-54.js",
".next/static/chunks/2zjueh7t2vecu.js",
".next/static/chunks/30wdrt2uam-rs.js",
".next/static/chunks/0n-zjr76qg7uq.js",
".next/static/chunks/0iec5q4ack_04.js",
".next/static/chunks/27jktro2p5rq9.js",
".next/static/chunks/turbopack-06glzjf65-whj.js"
]
}
]

View file

@ -0,0 +1,6 @@
{
"version": 1,
"hasExportPathMap": false,
"exportTrailingSlash": false,
"isNextImageImported": false
}

View file

@ -0,0 +1,13 @@
{
"pages": {
"/_app": []
},
"devFiles": [],
"polyfillFiles": [],
"lowPriorityFiles": [
"static/gYkJsTjiH4z33DmMxskx1/_buildManifest.js",
"static/gYkJsTjiH4z33DmMxskx1/_ssgManifest.js",
"static/gYkJsTjiH4z33DmMxskx1/_clientMiddlewareManifest.js"
],
"rootMainFiles": []
}

View file

@ -0,0 +1,68 @@
{
"version": 1,
"images": {
"deviceSizes": [
640,
750,
828,
1080,
1200,
1920,
2048,
3840
],
"imageSizes": [
32,
48,
64,
96,
128,
256,
384
],
"path": "/_next/image",
"loader": "default",
"loaderFile": "",
"domains": [],
"disableStaticImages": false,
"minimumCacheTTL": 14400,
"formats": [
"image/webp"
],
"maximumRedirects": 3,
"maximumResponseBody": 50000000,
"dangerouslyAllowLocalIP": false,
"dangerouslyAllowSVG": false,
"contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;",
"contentDispositionType": "attachment",
"localPatterns": [
{
"pathname": "^(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$))(?:(?:(?!(?:^|\\/)\\.{1,2}(?:\\/|$)).)*?)\\/?)$",
"search": ""
}
],
"remotePatterns": [],
"qualities": [
75
],
"unoptimized": false,
"customCacheHandler": false,
"sizes": [
640,
750,
828,
1080,
1200,
1920,
2048,
3840,
32,
48,
64,
96,
128,
256,
384
]
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"type": "commonjs"}

View file

@ -0,0 +1,426 @@
{
"version": 4,
"routes": {
"/": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/",
"dataRoute": "/index.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/_global-error": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/_global-error",
"dataRoute": "/_global-error.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/_not-found": {
"initialStatus": 404,
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/_not-found",
"dataRoute": "/_not-found.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/contacts": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/contacts",
"dataRoute": "/contacts.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/customers": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/customers",
"dataRoute": "/customers.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/dashboard": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/dashboard",
"dataRoute": "/dashboard.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/devices": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/devices",
"dataRoute": "/devices.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/documents": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/documents",
"dataRoute": "/documents.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/equipment": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/equipment",
"dataRoute": "/equipment.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/icon.svg": {
"initialHeaders": {
"cache-control": "public, max-age=0, must-revalidate",
"content-type": "image/svg+xml",
"x-next-cache-tags": "_N_T_/layout,_N_T_/icon.svg/layout,_N_T_/icon.svg/route,_N_T_/icon.svg"
},
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/icon.svg",
"dataRoute": null,
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/locations": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/locations",
"dataRoute": "/locations.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/login": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/login",
"dataRoute": "/login.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/profile/security": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/profile/security",
"dataRoute": "/profile/security.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/users": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/users",
"dataRoute": "/users.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/validations": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/validations",
"dataRoute": "/validations.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/validations/new": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/validations/new",
"dataRoute": "/validations/new.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
},
"/validations/quick-start": {
"experimentalBypassFor": [
{
"type": "header",
"key": "next-action"
},
{
"type": "header",
"key": "content-type",
"value": "multipart/form-data;.*"
}
],
"initialRevalidateSeconds": false,
"srcRoute": "/validations/quick-start",
"dataRoute": "/validations/quick-start.rsc",
"allowHeader": [
"host",
"x-matched-path",
"x-prerender-revalidate",
"x-prerender-revalidate-if-generated",
"x-next-revalidated-tags",
"x-next-revalidate-tag-token"
]
}
},
"dynamicRoutes": {},
"notFoundRoutes": [],
"preview": {
"previewModeId": "0f172cc22924763dbc2171b120c8e101",
"previewModeSigningKey": "edaf77e3d43cb1652a2c42b9827062f602086c8aae104689b67ca3f7f4907b0c",
"previewModeEncryptionKey": "1a645d1d69a5d15a9c01f8a02a837daa722446dbaa1ad52098685247ffb9188c"
}
}

View file

@ -0,0 +1,334 @@
self.__SERVER_FILES_MANIFEST={
"version": 1,
"config": {
"env": {},
"webpack": null,
"typescript": {
"ignoreBuildErrors": false
},
"typedRoutes": false,
"distDir": ".next",
"cleanDistDir": true,
"assetPrefix": "",
"cacheMaxMemorySize": 52428800,
"configOrigin": "next.config.ts",
"useFileSystemPublicRoutes": true,
"generateEtags": true,
"pageExtensions": [
"tsx",
"ts",
"jsx",
"js"
],
"poweredByHeader": true,
"compress": true,
"images": {
"deviceSizes": [
640,
750,
828,
1080,
1200,
1920,
2048,
3840
],
"imageSizes": [
32,
48,
64,
96,
128,
256,
384
],
"path": "/_next/image",
"loader": "default",
"loaderFile": "",
"domains": [],
"disableStaticImages": false,
"minimumCacheTTL": 14400,
"formats": [
"image/webp"
],
"maximumRedirects": 3,
"maximumResponseBody": 50000000,
"dangerouslyAllowLocalIP": false,
"dangerouslyAllowSVG": false,
"contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;",
"contentDispositionType": "attachment",
"localPatterns": [
{
"pathname": "**",
"search": ""
}
],
"remotePatterns": [],
"qualities": [
75
],
"unoptimized": false,
"customCacheHandler": false
},
"devIndicators": {
"position": "bottom-left"
},
"onDemandEntries": {
"maxInactiveAge": 60000,
"pagesBufferLength": 5
},
"basePath": "",
"sassOptions": {},
"trailingSlash": false,
"i18n": null,
"productionBrowserSourceMaps": false,
"excludeDefaultMomentLocales": true,
"reactProductionProfiling": false,
"reactStrictMode": null,
"reactMaxHeadersLength": 6000,
"httpAgentOptions": {
"keepAlive": true
},
"logging": {
"serverFunctions": true,
"browserToTerminal": "warn"
},
"compiler": {},
"expireTime": 31536000,
"staticPageGenerationTimeout": 60,
"output": "standalone",
"modularizeImports": {
"@mui/icons-material": {
"transform": "@mui/icons-material/{{member}}"
},
"lodash": {
"transform": "lodash/{{member}}"
}
},
"outputFileTracingRoot": "/Users/schubertferenc/schubamed/Validation_Suite/validation-suite/frontend/atlas",
"cacheComponents": false,
"cacheLife": {
"default": {
"stale": 300,
"revalidate": 900,
"expire": 4294967294
},
"seconds": {
"stale": 30,
"revalidate": 1,
"expire": 60
},
"minutes": {
"stale": 300,
"revalidate": 60,
"expire": 3600
},
"hours": {
"stale": 300,
"revalidate": 3600,
"expire": 86400
},
"days": {
"stale": 300,
"revalidate": 86400,
"expire": 604800
},
"weeks": {
"stale": 300,
"revalidate": 604800,
"expire": 2592000
},
"max": {
"stale": 300,
"revalidate": 2592000,
"expire": 31536000
}
},
"cacheHandlers": {},
"experimental": {
"appNewScrollHandler": false,
"useSkewCookie": false,
"cssChunking": true,
"multiZoneDraftMode": false,
"appNavFailHandling": false,
"prerenderEarlyExit": true,
"serverMinification": true,
"linkNoTouchStart": false,
"caseSensitiveRoutes": false,
"cachedNavigations": false,
"partialFallbacks": false,
"dynamicOnHover": false,
"varyParams": false,
"prefetchInlining": false,
"preloadEntriesOnStart": true,
"clientRouterFilter": true,
"clientRouterFilterRedirects": false,
"fetchCacheKeyPrefix": "",
"proxyPrefetch": "flexible",
"optimisticClientCache": true,
"manualClientBasePath": false,
"cpus": 9,
"memoryBasedWorkersCount": false,
"imgOptConcurrency": null,
"imgOptTimeoutInSeconds": 7,
"imgOptMaxInputPixels": 268402689,
"imgOptSequentialRead": null,
"imgOptSkipMetadata": null,
"isrFlushToDisk": true,
"workerThreads": false,
"optimizeCss": false,
"nextScriptWorkers": false,
"scrollRestoration": false,
"externalDir": false,
"disableOptimizedLoading": false,
"gzipSize": true,
"craCompat": false,
"esmExternals": true,
"fullySpecified": false,
"swcTraceProfiling": false,
"forceSwcTransforms": false,
"largePageDataBytes": 128000,
"typedEnv": false,
"parallelServerCompiles": false,
"parallelServerBuildTraces": false,
"ppr": false,
"authInterrupts": false,
"webpackMemoryOptimizations": false,
"optimizeServerReact": true,
"strictRouteTypes": false,
"viewTransition": false,
"removeUncaughtErrorAndRejectionListeners": false,
"validateRSCRequestHeaders": false,
"staleTimes": {
"dynamic": 0,
"static": 300
},
"reactDebugChannel": true,
"serverComponentsHmrCache": true,
"staticGenerationMaxConcurrency": 8,
"staticGenerationMinPagesPerWorker": 25,
"transitionIndicator": false,
"gestureTransition": false,
"inlineCss": false,
"useCache": false,
"globalNotFound": false,
"browserDebugInfoInTerminal": "warn",
"lockDistDir": true,
"proxyClientMaxBodySize": 10485760,
"hideLogsAfterAbort": false,
"mcpServer": true,
"turbopackFileSystemCacheForDev": true,
"turbopackFileSystemCacheForBuild": false,
"turbopackInferModuleSideEffects": true,
"turbopackPluginRuntimeStrategy": "childProcesses",
"optimizePackageImports": [
"lucide-react",
"date-fns",
"lodash-es",
"ramda",
"antd",
"react-bootstrap",
"ahooks",
"@ant-design/icons",
"@headlessui/react",
"@headlessui-float/react",
"@heroicons/react/20/solid",
"@heroicons/react/24/solid",
"@heroicons/react/24/outline",
"@visx/visx",
"@tremor/react",
"rxjs",
"@mui/material",
"@mui/icons-material",
"recharts",
"react-use",
"effect",
"@effect/schema",
"@effect/platform",
"@effect/platform-node",
"@effect/platform-browser",
"@effect/platform-bun",
"@effect/sql",
"@effect/sql-mssql",
"@effect/sql-mysql2",
"@effect/sql-pg",
"@effect/sql-sqlite-node",
"@effect/sql-sqlite-bun",
"@effect/sql-sqlite-wasm",
"@effect/sql-sqlite-react-native",
"@effect/rpc",
"@effect/rpc-http",
"@effect/typeclass",
"@effect/experimental",
"@effect/opentelemetry",
"@material-ui/core",
"@material-ui/icons",
"@tabler/icons-react",
"mui-core",
"react-icons/ai",
"react-icons/bi",
"react-icons/bs",
"react-icons/cg",
"react-icons/ci",
"react-icons/di",
"react-icons/fa",
"react-icons/fa6",
"react-icons/fc",
"react-icons/fi",
"react-icons/gi",
"react-icons/go",
"react-icons/gr",
"react-icons/hi",
"react-icons/hi2",
"react-icons/im",
"react-icons/io",
"react-icons/io5",
"react-icons/lia",
"react-icons/lib",
"react-icons/lu",
"react-icons/md",
"react-icons/pi",
"react-icons/ri",
"react-icons/rx",
"react-icons/si",
"react-icons/sl",
"react-icons/tb",
"react-icons/tfi",
"react-icons/ti",
"react-icons/vsc",
"react-icons/wi"
],
"trustHostHeader": false,
"isExperimentalCompile": false
},
"htmlLimitedBots": "[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight",
"bundlePagesRouterDependencies": false,
"configFileName": "next.config.ts",
"turbopack": {
"root": "/Users/schubertferenc/schubamed/Validation_Suite/validation-suite/frontend/atlas"
},
"distDirRoot": ".next"
},
"appDir": "/Users/schubertferenc/schubamed/Validation_Suite/validation-suite/frontend/atlas",
"relativeAppDir": "",
"files": [
".next/package.json",
".next/routes-manifest.json",
".next/server/pages-manifest.json",
".next/build-manifest.json",
".next/prerender-manifest.json",
".next/server/functions-config-manifest.json",
".next/server/middleware-manifest.json",
".next/server/middleware-build-manifest.js",
".next/server/app-paths-manifest.json",
".next/app-path-routes-manifest.json",
".next/server/server-reference-manifest.js",
".next/server/server-reference-manifest.json",
".next/server/prefetch-hints.json",
".next/BUILD_ID",
".next/server/next-font-manifest.js",
".next/server/next-font-manifest.json",
".next/required-server-files.json"
],
"ignore": []
}

View file

@ -0,0 +1,334 @@
{
"version": 1,
"config": {
"env": {},
"webpack": null,
"typescript": {
"ignoreBuildErrors": false
},
"typedRoutes": false,
"distDir": ".next",
"cleanDistDir": true,
"assetPrefix": "",
"cacheMaxMemorySize": 52428800,
"configOrigin": "next.config.ts",
"useFileSystemPublicRoutes": true,
"generateEtags": true,
"pageExtensions": [
"tsx",
"ts",
"jsx",
"js"
],
"poweredByHeader": true,
"compress": true,
"images": {
"deviceSizes": [
640,
750,
828,
1080,
1200,
1920,
2048,
3840
],
"imageSizes": [
32,
48,
64,
96,
128,
256,
384
],
"path": "/_next/image",
"loader": "default",
"loaderFile": "",
"domains": [],
"disableStaticImages": false,
"minimumCacheTTL": 14400,
"formats": [
"image/webp"
],
"maximumRedirects": 3,
"maximumResponseBody": 50000000,
"dangerouslyAllowLocalIP": false,
"dangerouslyAllowSVG": false,
"contentSecurityPolicy": "script-src 'none'; frame-src 'none'; sandbox;",
"contentDispositionType": "attachment",
"localPatterns": [
{
"pathname": "**",
"search": ""
}
],
"remotePatterns": [],
"qualities": [
75
],
"unoptimized": false,
"customCacheHandler": false
},
"devIndicators": {
"position": "bottom-left"
},
"onDemandEntries": {
"maxInactiveAge": 60000,
"pagesBufferLength": 5
},
"basePath": "",
"sassOptions": {},
"trailingSlash": false,
"i18n": null,
"productionBrowserSourceMaps": false,
"excludeDefaultMomentLocales": true,
"reactProductionProfiling": false,
"reactStrictMode": null,
"reactMaxHeadersLength": 6000,
"httpAgentOptions": {
"keepAlive": true
},
"logging": {
"serverFunctions": true,
"browserToTerminal": "warn"
},
"compiler": {},
"expireTime": 31536000,
"staticPageGenerationTimeout": 60,
"output": "standalone",
"modularizeImports": {
"@mui/icons-material": {
"transform": "@mui/icons-material/{{member}}"
},
"lodash": {
"transform": "lodash/{{member}}"
}
},
"outputFileTracingRoot": "/Users/schubertferenc/schubamed/Validation_Suite/validation-suite/frontend/atlas",
"cacheComponents": false,
"cacheLife": {
"default": {
"stale": 300,
"revalidate": 900,
"expire": 4294967294
},
"seconds": {
"stale": 30,
"revalidate": 1,
"expire": 60
},
"minutes": {
"stale": 300,
"revalidate": 60,
"expire": 3600
},
"hours": {
"stale": 300,
"revalidate": 3600,
"expire": 86400
},
"days": {
"stale": 300,
"revalidate": 86400,
"expire": 604800
},
"weeks": {
"stale": 300,
"revalidate": 604800,
"expire": 2592000
},
"max": {
"stale": 300,
"revalidate": 2592000,
"expire": 31536000
}
},
"cacheHandlers": {},
"experimental": {
"appNewScrollHandler": false,
"useSkewCookie": false,
"cssChunking": true,
"multiZoneDraftMode": false,
"appNavFailHandling": false,
"prerenderEarlyExit": true,
"serverMinification": true,
"linkNoTouchStart": false,
"caseSensitiveRoutes": false,
"cachedNavigations": false,
"partialFallbacks": false,
"dynamicOnHover": false,
"varyParams": false,
"prefetchInlining": false,
"preloadEntriesOnStart": true,
"clientRouterFilter": true,
"clientRouterFilterRedirects": false,
"fetchCacheKeyPrefix": "",
"proxyPrefetch": "flexible",
"optimisticClientCache": true,
"manualClientBasePath": false,
"cpus": 9,
"memoryBasedWorkersCount": false,
"imgOptConcurrency": null,
"imgOptTimeoutInSeconds": 7,
"imgOptMaxInputPixels": 268402689,
"imgOptSequentialRead": null,
"imgOptSkipMetadata": null,
"isrFlushToDisk": true,
"workerThreads": false,
"optimizeCss": false,
"nextScriptWorkers": false,
"scrollRestoration": false,
"externalDir": false,
"disableOptimizedLoading": false,
"gzipSize": true,
"craCompat": false,
"esmExternals": true,
"fullySpecified": false,
"swcTraceProfiling": false,
"forceSwcTransforms": false,
"largePageDataBytes": 128000,
"typedEnv": false,
"parallelServerCompiles": false,
"parallelServerBuildTraces": false,
"ppr": false,
"authInterrupts": false,
"webpackMemoryOptimizations": false,
"optimizeServerReact": true,
"strictRouteTypes": false,
"viewTransition": false,
"removeUncaughtErrorAndRejectionListeners": false,
"validateRSCRequestHeaders": false,
"staleTimes": {
"dynamic": 0,
"static": 300
},
"reactDebugChannel": true,
"serverComponentsHmrCache": true,
"staticGenerationMaxConcurrency": 8,
"staticGenerationMinPagesPerWorker": 25,
"transitionIndicator": false,
"gestureTransition": false,
"inlineCss": false,
"useCache": false,
"globalNotFound": false,
"browserDebugInfoInTerminal": "warn",
"lockDistDir": true,
"proxyClientMaxBodySize": 10485760,
"hideLogsAfterAbort": false,
"mcpServer": true,
"turbopackFileSystemCacheForDev": true,
"turbopackFileSystemCacheForBuild": false,
"turbopackInferModuleSideEffects": true,
"turbopackPluginRuntimeStrategy": "childProcesses",
"optimizePackageImports": [
"lucide-react",
"date-fns",
"lodash-es",
"ramda",
"antd",
"react-bootstrap",
"ahooks",
"@ant-design/icons",
"@headlessui/react",
"@headlessui-float/react",
"@heroicons/react/20/solid",
"@heroicons/react/24/solid",
"@heroicons/react/24/outline",
"@visx/visx",
"@tremor/react",
"rxjs",
"@mui/material",
"@mui/icons-material",
"recharts",
"react-use",
"effect",
"@effect/schema",
"@effect/platform",
"@effect/platform-node",
"@effect/platform-browser",
"@effect/platform-bun",
"@effect/sql",
"@effect/sql-mssql",
"@effect/sql-mysql2",
"@effect/sql-pg",
"@effect/sql-sqlite-node",
"@effect/sql-sqlite-bun",
"@effect/sql-sqlite-wasm",
"@effect/sql-sqlite-react-native",
"@effect/rpc",
"@effect/rpc-http",
"@effect/typeclass",
"@effect/experimental",
"@effect/opentelemetry",
"@material-ui/core",
"@material-ui/icons",
"@tabler/icons-react",
"mui-core",
"react-icons/ai",
"react-icons/bi",
"react-icons/bs",
"react-icons/cg",
"react-icons/ci",
"react-icons/di",
"react-icons/fa",
"react-icons/fa6",
"react-icons/fc",
"react-icons/fi",
"react-icons/gi",
"react-icons/go",
"react-icons/gr",
"react-icons/hi",
"react-icons/hi2",
"react-icons/im",
"react-icons/io",
"react-icons/io5",
"react-icons/lia",
"react-icons/lib",
"react-icons/lu",
"react-icons/md",
"react-icons/pi",
"react-icons/ri",
"react-icons/rx",
"react-icons/si",
"react-icons/sl",
"react-icons/tb",
"react-icons/tfi",
"react-icons/ti",
"react-icons/vsc",
"react-icons/wi"
],
"trustHostHeader": false,
"isExperimentalCompile": false
},
"htmlLimitedBots": "[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight",
"bundlePagesRouterDependencies": false,
"configFileName": "next.config.ts",
"turbopack": {
"root": "/Users/schubertferenc/schubamed/Validation_Suite/validation-suite/frontend/atlas"
},
"distDirRoot": ".next"
},
"appDir": "/Users/schubertferenc/schubamed/Validation_Suite/validation-suite/frontend/atlas",
"relativeAppDir": "",
"files": [
".next/package.json",
".next/routes-manifest.json",
".next/server/pages-manifest.json",
".next/build-manifest.json",
".next/prerender-manifest.json",
".next/server/functions-config-manifest.json",
".next/server/middleware-manifest.json",
".next/server/middleware-build-manifest.js",
".next/server/app-paths-manifest.json",
".next/app-path-routes-manifest.json",
".next/server/server-reference-manifest.js",
".next/server/server-reference-manifest.json",
".next/server/prefetch-hints.json",
".next/BUILD_ID",
".next/server/next-font-manifest.js",
".next/server/next-font-manifest.json",
".next/required-server-files.json"
],
"ignore": []
}

View file

@ -0,0 +1,190 @@
{
"version": 3,
"pages404": true,
"appType": "app",
"caseSensitive": false,
"basePath": "",
"redirects": [
{
"source": "/:path+/",
"destination": "/:path+",
"internal": true,
"priority": true,
"statusCode": 308,
"regex": "^(?:/((?:[^/]+?)(?:/(?:[^/]+?))*))/$"
}
],
"headers": [],
"onMatchHeaders": [],
"rewrites": {
"beforeFiles": [],
"afterFiles": [],
"fallback": []
},
"dynamicRoutes": [
{
"page": "/api/v1/[...path]",
"regex": "^/api/v1/(.+?)(?:/)?$",
"routeKeys": {
"nxtPpath": "nxtPpath"
},
"namedRegex": "^/api/v1/(?<nxtPpath>.+?)(?:/)?$"
},
{
"page": "/validations/[id]/edit",
"regex": "^/validations/([^/]+?)/edit(?:/)?$",
"routeKeys": {
"nxtPid": "nxtPid"
},
"namedRegex": "^/validations/(?<nxtPid>[^/]+?)/edit(?:/)?$"
},
{
"page": "/validations/[id]/preview",
"regex": "^/validations/([^/]+?)/preview(?:/)?$",
"routeKeys": {
"nxtPid": "nxtPid"
},
"namedRegex": "^/validations/(?<nxtPid>[^/]+?)/preview(?:/)?$"
}
],
"staticRoutes": [
{
"page": "/",
"regex": "^/(?:/)?$",
"routeKeys": {},
"namedRegex": "^/(?:/)?$"
},
{
"page": "/_global-error",
"regex": "^/_global\\-error(?:/)?$",
"routeKeys": {},
"namedRegex": "^/_global\\-error(?:/)?$"
},
{
"page": "/_not-found",
"regex": "^/_not\\-found(?:/)?$",
"routeKeys": {},
"namedRegex": "^/_not\\-found(?:/)?$"
},
{
"page": "/api/login",
"regex": "^/api/login(?:/)?$",
"routeKeys": {},
"namedRegex": "^/api/login(?:/)?$"
},
{
"page": "/api/logout",
"regex": "^/api/logout(?:/)?$",
"routeKeys": {},
"namedRegex": "^/api/logout(?:/)?$"
},
{
"page": "/api/me",
"regex": "^/api/me(?:/)?$",
"routeKeys": {},
"namedRegex": "^/api/me(?:/)?$"
},
{
"page": "/contacts",
"regex": "^/contacts(?:/)?$",
"routeKeys": {},
"namedRegex": "^/contacts(?:/)?$"
},
{
"page": "/customers",
"regex": "^/customers(?:/)?$",
"routeKeys": {},
"namedRegex": "^/customers(?:/)?$"
},
{
"page": "/dashboard",
"regex": "^/dashboard(?:/)?$",
"routeKeys": {},
"namedRegex": "^/dashboard(?:/)?$"
},
{
"page": "/devices",
"regex": "^/devices(?:/)?$",
"routeKeys": {},
"namedRegex": "^/devices(?:/)?$"
},
{
"page": "/documents",
"regex": "^/documents(?:/)?$",
"routeKeys": {},
"namedRegex": "^/documents(?:/)?$"
},
{
"page": "/equipment",
"regex": "^/equipment(?:/)?$",
"routeKeys": {},
"namedRegex": "^/equipment(?:/)?$"
},
{
"page": "/icon.svg",
"regex": "^/icon\\.svg(?:/)?$",
"routeKeys": {},
"namedRegex": "^/icon\\.svg(?:/)?$"
},
{
"page": "/locations",
"regex": "^/locations(?:/)?$",
"routeKeys": {},
"namedRegex": "^/locations(?:/)?$"
},
{
"page": "/login",
"regex": "^/login(?:/)?$",
"routeKeys": {},
"namedRegex": "^/login(?:/)?$"
},
{
"page": "/profile/security",
"regex": "^/profile/security(?:/)?$",
"routeKeys": {},
"namedRegex": "^/profile/security(?:/)?$"
},
{
"page": "/users",
"regex": "^/users(?:/)?$",
"routeKeys": {},
"namedRegex": "^/users(?:/)?$"
},
{
"page": "/validations",
"regex": "^/validations(?:/)?$",
"routeKeys": {},
"namedRegex": "^/validations(?:/)?$"
},
{
"page": "/validations/new",
"regex": "^/validations/new(?:/)?$",
"routeKeys": {},
"namedRegex": "^/validations/new(?:/)?$"
},
{
"page": "/validations/quick-start",
"regex": "^/validations/quick\\-start(?:/)?$",
"routeKeys": {},
"namedRegex": "^/validations/quick\\-start(?:/)?$"
}
],
"dataRoutes": [],
"rsc": {
"header": "rsc",
"varyHeader": "rsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch",
"prefetchHeader": "next-router-prefetch",
"didPostponeHeader": "x-nextjs-postponed",
"contentTypeHeader": "text/x-component",
"suffix": ".rsc",
"prefetchSegmentHeader": "next-router-segment-prefetch",
"prefetchSegmentSuffix": ".segment.rsc",
"prefetchSegmentDirSuffix": ".segments",
"clientParamParsing": false,
"dynamicRSCPrerender": false
},
"rewriteHeaders": {
"pathHeader": "x-nextjs-rewritten-path",
"queryHeader": "x-nextjs-rewritten-query"
}
}

View file

@ -0,0 +1,25 @@
{
"/(app)/contacts/page": "app/(app)/contacts/page.js",
"/(app)/customers/page": "app/(app)/customers/page.js",
"/(app)/dashboard/page": "app/(app)/dashboard/page.js",
"/(app)/devices/page": "app/(app)/devices/page.js",
"/(app)/documents/page": "app/(app)/documents/page.js",
"/(app)/equipment/page": "app/(app)/equipment/page.js",
"/(app)/locations/page": "app/(app)/locations/page.js",
"/(app)/profile/security/page": "app/(app)/profile/security/page.js",
"/(app)/users/page": "app/(app)/users/page.js",
"/(app)/validations/[id]/edit/page": "app/(app)/validations/[id]/edit/page.js",
"/(app)/validations/[id]/preview/page": "app/(app)/validations/[id]/preview/page.js",
"/(app)/validations/new/page": "app/(app)/validations/new/page.js",
"/(app)/validations/page": "app/(app)/validations/page.js",
"/(app)/validations/quick-start/page": "app/(app)/validations/quick-start/page.js",
"/(auth)/login/page": "app/(auth)/login/page.js",
"/_global-error/page": "app/_global-error/page.js",
"/_not-found/page": "app/_not-found/page.js",
"/api/login/route": "app/api/login/route.js",
"/api/logout/route": "app/api/logout/route.js",
"/api/me/route": "app/api/me/route.js",
"/api/v1/[...path]/route": "app/api/v1/[...path]/route.js",
"/icon.svg/route": "app/icon.svg/route.js",
"/page": "app/page.js"
}

View file

@ -0,0 +1,16 @@
var R=require("../../../chunks/ssr/[turbopack]_runtime.js")("server/app/(app)/contacts/page.js")
R.c("server/chunks/ssr/[root-of-the-server]__131fw97._.js")
R.c("server/chunks/ssr/node_modules_next_dist_0bw_x_7._.js")
R.c("server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1v8-mvc.js")
R.c("server/chunks/ssr/[root-of-the-server]__0_kl8he._.js")
R.c("server/chunks/ssr/[root-of-the-server]__0g84hko._.js")
R.c("server/chunks/ssr/app_layout_tsx_2144vk_._.js")
R.c("server/chunks/ssr/_0um1dzw._.js")
R.c("server/chunks/ssr/_0kezen4._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_0p8s4lh._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js")
R.c("server/chunks/ssr/_0b7nppq._.js")
R.c("server/chunks/ssr/_next-internal_server_app_(app)_contacts_page_actions_0xstysf.js")
R.m(71050)
module.exports=R.m(71050).exports

View file

@ -0,0 +1,5 @@
{
"version": 3,
"sources": [],
"sections": []
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
{
"/(app)/contacts/page": "app/(app)/contacts/page.js"
}

View file

@ -0,0 +1,18 @@
{
"devFiles": [],
"ampDevFiles": [],
"polyfillFiles": [
"static/chunks/0cz1d0mv5g_q7.js"
],
"lowPriorityFiles": [],
"rootMainFiles": [
"static/chunks/2zjueh7t2vecu.js",
"static/chunks/30wdrt2uam-rs.js",
"static/chunks/0n-zjr76qg7uq.js",
"static/chunks/0iec5q4ack_04.js",
"static/chunks/27jktro2p5rq9.js",
"static/chunks/turbopack-06glzjf65-whj.js"
],
"pages": {},
"ampFirstPages": []
}

View file

@ -0,0 +1,6 @@
{
"pages": {},
"app": {},
"appUsingSizeAdjust": false,
"pagesUsingSizeAdjust": false
}

View file

@ -0,0 +1,4 @@
{
"node": {},
"edge": {}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,16 @@
var R=require("../../../chunks/ssr/[turbopack]_runtime.js")("server/app/(app)/customers/page.js")
R.c("server/chunks/ssr/[root-of-the-server]__1a7ggz1._.js")
R.c("server/chunks/ssr/node_modules_next_dist_0bw_x_7._.js")
R.c("server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_081l-n0.js")
R.c("server/chunks/ssr/[root-of-the-server]__0_kl8he._.js")
R.c("server/chunks/ssr/[root-of-the-server]__0g84hko._.js")
R.c("server/chunks/ssr/app_layout_tsx_2144vk_._.js")
R.c("server/chunks/ssr/_0um1dzw._.js")
R.c("server/chunks/ssr/_0kezen4._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_0p8s4lh._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js")
R.c("server/chunks/ssr/_0b7nppq._.js")
R.c("server/chunks/ssr/_next-internal_server_app_(app)_customers_page_actions_0ypluz6.js")
R.m(99402)
module.exports=R.m(99402).exports

View file

@ -0,0 +1,5 @@
{
"version": 3,
"sources": [],
"sections": []
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
{
"/(app)/customers/page": "app/(app)/customers/page.js"
}

View file

@ -0,0 +1,18 @@
{
"devFiles": [],
"ampDevFiles": [],
"polyfillFiles": [
"static/chunks/0cz1d0mv5g_q7.js"
],
"lowPriorityFiles": [],
"rootMainFiles": [
"static/chunks/2zjueh7t2vecu.js",
"static/chunks/30wdrt2uam-rs.js",
"static/chunks/0n-zjr76qg7uq.js",
"static/chunks/0iec5q4ack_04.js",
"static/chunks/27jktro2p5rq9.js",
"static/chunks/turbopack-06glzjf65-whj.js"
],
"pages": {},
"ampFirstPages": []
}

View file

@ -0,0 +1,6 @@
{
"pages": {},
"app": {},
"appUsingSizeAdjust": false,
"pagesUsingSizeAdjust": false
}

View file

@ -0,0 +1,4 @@
{
"node": {},
"edge": {}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,16 @@
var R=require("../../../chunks/ssr/[turbopack]_runtime.js")("server/app/(app)/dashboard/page.js")
R.c("server/chunks/ssr/[root-of-the-server]__1igzz_l._.js")
R.c("server/chunks/ssr/node_modules_next_dist_0bw_x_7._.js")
R.c("server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1-h6epm.js")
R.c("server/chunks/ssr/[root-of-the-server]__0_kl8he._.js")
R.c("server/chunks/ssr/[root-of-the-server]__0g84hko._.js")
R.c("server/chunks/ssr/app_layout_tsx_2144vk_._.js")
R.c("server/chunks/ssr/_0um1dzw._.js")
R.c("server/chunks/ssr/_0kezen4._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_0p8s4lh._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js")
R.c("server/chunks/ssr/_0b7nppq._.js")
R.c("server/chunks/ssr/_next-internal_server_app_(app)_dashboard_page_actions_19--7_-.js")
R.m(96552)
module.exports=R.m(96552).exports

View file

@ -0,0 +1,5 @@
{
"version": 3,
"sources": [],
"sections": []
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
{
"/(app)/dashboard/page": "app/(app)/dashboard/page.js"
}

View file

@ -0,0 +1,18 @@
{
"devFiles": [],
"ampDevFiles": [],
"polyfillFiles": [
"static/chunks/0cz1d0mv5g_q7.js"
],
"lowPriorityFiles": [],
"rootMainFiles": [
"static/chunks/2zjueh7t2vecu.js",
"static/chunks/30wdrt2uam-rs.js",
"static/chunks/0n-zjr76qg7uq.js",
"static/chunks/0iec5q4ack_04.js",
"static/chunks/27jktro2p5rq9.js",
"static/chunks/turbopack-06glzjf65-whj.js"
],
"pages": {},
"ampFirstPages": []
}

View file

@ -0,0 +1,6 @@
{
"pages": {},
"app": {},
"appUsingSizeAdjust": false,
"pagesUsingSizeAdjust": false
}

View file

@ -0,0 +1,4 @@
{
"node": {},
"edge": {}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,16 @@
var R=require("../../../chunks/ssr/[turbopack]_runtime.js")("server/app/(app)/devices/page.js")
R.c("server/chunks/ssr/[root-of-the-server]__1az92__._.js")
R.c("server/chunks/ssr/node_modules_next_dist_0bw_x_7._.js")
R.c("server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1r3f_tz.js")
R.c("server/chunks/ssr/[root-of-the-server]__0_kl8he._.js")
R.c("server/chunks/ssr/[root-of-the-server]__0g84hko._.js")
R.c("server/chunks/ssr/app_layout_tsx_2144vk_._.js")
R.c("server/chunks/ssr/_0um1dzw._.js")
R.c("server/chunks/ssr/_0kezen4._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_0p8s4lh._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js")
R.c("server/chunks/ssr/_0b7nppq._.js")
R.c("server/chunks/ssr/_next-internal_server_app_(app)_devices_page_actions_0fljvmv.js")
R.m(89645)
module.exports=R.m(89645).exports

View file

@ -0,0 +1,5 @@
{
"version": 3,
"sources": [],
"sections": []
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
{
"/(app)/devices/page": "app/(app)/devices/page.js"
}

View file

@ -0,0 +1,18 @@
{
"devFiles": [],
"ampDevFiles": [],
"polyfillFiles": [
"static/chunks/0cz1d0mv5g_q7.js"
],
"lowPriorityFiles": [],
"rootMainFiles": [
"static/chunks/2zjueh7t2vecu.js",
"static/chunks/30wdrt2uam-rs.js",
"static/chunks/0n-zjr76qg7uq.js",
"static/chunks/0iec5q4ack_04.js",
"static/chunks/27jktro2p5rq9.js",
"static/chunks/turbopack-06glzjf65-whj.js"
],
"pages": {},
"ampFirstPages": []
}

View file

@ -0,0 +1,6 @@
{
"pages": {},
"app": {},
"appUsingSizeAdjust": false,
"pagesUsingSizeAdjust": false
}

View file

@ -0,0 +1,4 @@
{
"node": {},
"edge": {}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,16 @@
var R=require("../../../chunks/ssr/[turbopack]_runtime.js")("server/app/(app)/documents/page.js")
R.c("server/chunks/ssr/[root-of-the-server]__0rekl0u._.js")
R.c("server/chunks/ssr/node_modules_next_dist_0bw_x_7._.js")
R.c("server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0ufybhg.js")
R.c("server/chunks/ssr/[root-of-the-server]__0_kl8he._.js")
R.c("server/chunks/ssr/[root-of-the-server]__0g84hko._.js")
R.c("server/chunks/ssr/app_layout_tsx_2144vk_._.js")
R.c("server/chunks/ssr/_0um1dzw._.js")
R.c("server/chunks/ssr/_0kezen4._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_0p8s4lh._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js")
R.c("server/chunks/ssr/_0b7nppq._.js")
R.c("server/chunks/ssr/_next-internal_server_app_(app)_documents_page_actions_0y28ku2.js")
R.m(8223)
module.exports=R.m(8223).exports

View file

@ -0,0 +1,5 @@
{
"version": 3,
"sources": [],
"sections": []
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
{
"/(app)/documents/page": "app/(app)/documents/page.js"
}

View file

@ -0,0 +1,18 @@
{
"devFiles": [],
"ampDevFiles": [],
"polyfillFiles": [
"static/chunks/0cz1d0mv5g_q7.js"
],
"lowPriorityFiles": [],
"rootMainFiles": [
"static/chunks/2zjueh7t2vecu.js",
"static/chunks/30wdrt2uam-rs.js",
"static/chunks/0n-zjr76qg7uq.js",
"static/chunks/0iec5q4ack_04.js",
"static/chunks/27jktro2p5rq9.js",
"static/chunks/turbopack-06glzjf65-whj.js"
],
"pages": {},
"ampFirstPages": []
}

View file

@ -0,0 +1,6 @@
{
"pages": {},
"app": {},
"appUsingSizeAdjust": false,
"pagesUsingSizeAdjust": false
}

View file

@ -0,0 +1,4 @@
{
"node": {},
"edge": {}
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,16 @@
var R=require("../../../chunks/ssr/[turbopack]_runtime.js")("server/app/(app)/equipment/page.js")
R.c("server/chunks/ssr/[root-of-the-server]__1yyih4q._.js")
R.c("server/chunks/ssr/node_modules_next_dist_0bw_x_7._.js")
R.c("server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1iadf3k.js")
R.c("server/chunks/ssr/[root-of-the-server]__0_kl8he._.js")
R.c("server/chunks/ssr/[root-of-the-server]__0g84hko._.js")
R.c("server/chunks/ssr/app_layout_tsx_2144vk_._.js")
R.c("server/chunks/ssr/_0um1dzw._.js")
R.c("server/chunks/ssr/_0kezen4._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_0p8s4lh._.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_unauthorized_0l_sp0x.js")
R.c("server/chunks/ssr/node_modules_next_dist_client_components_builtin_global-error_0-o-goa.js")
R.c("server/chunks/ssr/_0b7nppq._.js")
R.c("server/chunks/ssr/_next-internal_server_app_(app)_equipment_page_actions_1kpyh4_.js")
R.m(82854)
module.exports=R.m(82854).exports

Some files were not shown because too many files have changed in this diff Show more