Compare commits

...

35 Commits

Author SHA1 Message Date
e4028e6ac1 8.0.0 2025-03-24 08:04:14 +00:00
dfee187404 BREAKING CHANGE(tsclass): new document base type for invoice, contract etc. 2025-03-24 08:04:14 +00:00
065b5faba2 Merge pull request 'feat/TInvoice' (#2) from feat/TInvoice into master
Reviewed-on: #2
Reviewed-by: Dominik Schwank <dominik@schwank.cc>
2025-03-24 07:55:21 +00:00
7ddc98d9c8 remove obsolete files 2025-03-22 23:42:45 +00:00
65503e554b feat(business): Add TDocumentEnvelope as common base for letters and contracts
- Created a new TDocumentEnvelope base type for shared document properties
- Refactored TLetterEnvelope to extend from TDocumentEnvelope
- Refactored TContractEnvelope to extend from TDocumentEnvelope
- Centralized common fields like version tracking, date, and formatting
2025-03-22 23:42:22 +00:00
9b66c438b4 feat(business): Refactor TContract to use structured paragraphs and envelope pattern
- Replaced single markdown string with structured paragraphs
- Implemented TContractEnvelope pattern for different contract types
- Added specific contract types (employment, NDA, service, lease)
- Added metadata for dates, status, versioning, and attachments
- Removed legacy contract interface
2025-03-22 23:34:45 +00:00
0c977bd869 feat(finance): Refactor TInvoice to use TLetterEnvelope pattern
- Implemented envelope pattern for TInvoice using business.TLetterEnvelope
- Separated TInvoice into TCreditNote and TDebitNote types
- Fixed IInvoiceItem references to use TInvoiceItem
- Added compatibility interface for IInvoiceItem
2025-03-22 21:38:50 +00:00
6d3f097bb8 on the way to new letter / invoice relationship 2025-03-22 21:27:20 +00:00
d87b50fb45 7.1.1 2025-03-20 19:25:56 +00:00
4f72f484d0 fix(finance): Add optional date property to the IInvoice interface 2025-03-20 19:25:56 +00:00
7931d458c5 7.1.0 2025-03-20 18:56:35 +00:00
d5b21e6567 feat(ts/finance/invoice): Add electronicAddress field to IInvoice for circular xinvoice support 2025-03-20 18:56:35 +00:00
1ccafa8c87 7.0.0 2025-03-20 18:53:49 +00:00
850d56df8b BREAKING CHANGE(business/address): Remove eAddress property from IAddress interface 2025-03-20 18:53:49 +00:00
dead451ab0 6.1.2 2025-03-20 17:52:17 +00:00
d7855494a7 fix(business/address): Improve documentation comments for address interface properties 2025-03-20 17:52:17 +00:00
0a12915c7e 6.1.1 2025-03-20 17:44:10 +00:00
9a942cafa5 fix(finance): Add clarifying comment for the buyerReference field in the invoice interface 2025-03-20 17:44:10 +00:00
0292b4fef4 6.1.0 2025-03-20 17:34:56 +00:00
2d9d2a5a47 feat(business/address): Add optional countryCode and coordinates properties to IAddress interface 2025-03-20 17:34:56 +00:00
079e315b23 6.0.1 2025-03-19 14:17:43 +00:00
caf3e4766f fix(business): Remove exports for company and person modules from the business index 2025-03-19 14:17:43 +00:00
50b5630aed 6.0.0 2025-03-19 14:16:55 +00:00
a8776be6b8 BREAKING CHANGE(TContact): new structure around TContact that combines functionality of previous interfaces like ICompany and IPerson 2025-03-19 14:16:55 +00:00
4e173d4dd4 Merge pull request 'feat: add registration info and refactor contact' (#1) from feat/add-registration-info into master
Reviewed-on: #1
2025-03-19 14:08:30 +00:00
edcbdea31f chore: fix typo 2025-03-18 16:49:51 +00:00
6072974bda feat: add registration info and refactor contact 2025-03-17 19:15:08 +00:00
8883bf181e 5.0.0 2025-03-11 12:07:33 +00:00
cd09a70232 BREAKING CHANGE(network): Update reverse proxy configuration to support multiple destination IPs and ports 2025-03-11 12:07:33 +00:00
e6811c75fc 4.4.4 2025-03-10 15:20:24 +00:00
e0ba9c6cef fix(business): Fixes typo in ILetter interface 2025-03-10 15:20:24 +00:00
90c56c6d4f 4.4.3 2025-03-07 14:21:32 +00:00
91caa9a747 fix(network): Fix destinationPort type for IReverseProxyConfig 2025-03-07 14:21:32 +00:00
115250edab 4.4.2 2025-03-07 14:20:18 +00:00
1127b8961f fix(dependencies): Updated package dependencies for improved stability and performance. 2025-03-07 14:20:18 +00:00
21 changed files with 3147 additions and 2516 deletions

View File

@ -1,5 +1,78 @@
# Changelog
## 2025-03-24 - 8.0.0 - BREAKING CHANGE(tsclass)
Trigger patch release with no code changes
## 2025-03-20 - 7.1.1 - fix(finance)
Add optional date property to the IInvoice interface
- Introduced an optional 'date' field with explanatory comments to capture the invoice date if not provided from the encompassing letter
## 2025-03-20 - 7.1.0 - feat(ts/finance/invoice)
Add electronicAddress field to IInvoice for circular xinvoice support
- Introduce optional electronicAddress property with scheme and value
- Enhance documentation for buyer reference in invoice interface
## 2025-03-20 - 7.0.0 - BREAKING CHANGE(business/address)
Remove eAddress property from IAddress interface
- Removed eAddress field that allowed storage of electronic contact means (phone, email, peppolId)
## 2025-03-20 - 6.1.2 - fix(business/address)
Improve documentation comments for address interface properties
- Added detailed comments for the 'coordinates' property to explain its usage
- Added detailed comments for the 'eAddress' property to describe the storage of electronic contact information
## 2025-03-20 - 6.1.1 - fix(finance)
Add clarifying comment for the buyerReference field in the invoice interface
- Document buyerReference as an optional field to help buyers identify the invoice
## 2025-03-20 - 6.1.0 - feat(business/address)
Add optional countryCode and coordinates properties to IAddress interface
- Extend address interface with an optional countryCode property
- Add optional coordinates object with lat and lng for geographic metadata
## 2025-03-19 - 6.0.1 - fix(business)
Remove exports for 'company' and 'person' modules from the business index
- Removed export statement for './company.js' in ts/business/index.ts
- Removed export statement for './person.js' in ts/business/index.ts
## 2025-03-19 - 6.0.0 - BREAKING CHANGE(TContact)
Reaffirm project metadata and documentation consistency
- Verified commitinfo data, package.json, and README content for correctness
- No functional code changes were introduced
## 2025-03-11 - 5.0.0 - BREAKING CHANGE(network)
Update reverse proxy configuration to support multiple destination IPs and ports
- Replaced 'destinationIp' and 'destinationPort' with 'destinationIps' (array) and 'destinationPorts' (array) to enable multiple destinations
## 2025-03-10 - 4.4.4 - fix(business)
Fixes typo in ILetter interface
- Removed unused property 'letterData' from ILetter content structure.
## 2025-03-07 - 4.4.3 - fix(network)
Fix destinationPort type for IReverseProxyConfig
- Corrected the type of destinationPort in IReverseProxyConfig from 'string' to 'number'.
## 2025-03-07 - 4.4.2 - fix(dependencies)
Updated package dependencies for improved stability and performance.
- Updated 'type-fest' dependency to version ^4.37.0.
- Updated '@git.zone/tsbuild' to version ^2.2.6.
- Updated '@git.zone/tstest' to version ^1.0.96.
- Updated '@push.rocks/tapbundle' to ^5.5.6.
- Updated '@types/node' to ^22.13.9.
## 2025-03-07 - 4.4.1 - fix(business)
Fix missing letterData property in ILetter interface.

View File

@ -1,6 +1,6 @@
{
"name": "@tsclass/tsclass",
"version": "4.4.1",
"version": "8.0.0",
"private": false,
"description": "Provides TypeScript definitions for various business, financial, networking, content, and other common classes.",
"main": "dist_ts/index.js",
@ -37,14 +37,14 @@
},
"homepage": "https://github.com/tsclass/tsclass#readme",
"dependencies": {
"type-fest": "^4.30.0"
"type-fest": "^4.37.0"
},
"devDependencies": {
"@git.zone/tsbuild": "^2.2.0",
"@git.zone/tsbuild": "^2.3.2",
"@git.zone/tsrun": "^1.3.3",
"@git.zone/tstest": "^1.0.90",
"@push.rocks/tapbundle": "^5.5.3",
"@types/node": "^22.10.2"
"@git.zone/tstest": "^1.0.96",
"@push.rocks/tapbundle": "^5.6.0",
"@types/node": "^22.13.11"
},
"files": [
"ts/**/*",

4967
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@ The business domain includes classes for managing contacts, companies, and proje
```typescript
import { business } from '@tsclass/tsclass';
const companyContact: business.IContact = {
const companyContact: business.TContact = {
type: 'company',
name: 'Example Company',
address: {
@ -48,7 +48,7 @@ const companyContact: business.IContact = {
email: 'contact@example.com'
};
const exampleCompany: business.ICompany = {
const exampleCompany: business.TCompany = {
name: 'Example Company',
foundedDate: {
day: 1,

View File

@ -3,7 +3,7 @@ import { tap, expect } from '@push.rocks/tapbundle';
import * as tsclass from '../ts/index.js';
tap.test('should assign a correct type', async () => {
let contact: tsclass.business.IContact;
let contact: tsclass.business.TContact;
});
tap.start();

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@tsclass/tsclass',
version: '4.4.1',
version: '8.0.0',
description: 'Provides TypeScript definitions for various business, financial, networking, content, and other common classes.'
}

View File

@ -1,5 +0,0 @@
import { type IInvoice } from "../finance/invoice.js";
export function createLetterFromInvoice(invoiceArg: IInvoice) {
}

View File

@ -1 +0,0 @@
export * from './finance.js';

View File

@ -5,4 +5,13 @@ export interface IAddress {
postalCode: string;
city: string;
country: string;
countryCode?: string;
/**
* allows storage of coordinates for this address
* useful for countries where addresses are not unique
*/
coordinates?: {
lat: number;
lng: number;
};
}

View File

@ -1,20 +0,0 @@
import { business, general } from '../index.js';
/**
* describes a company's lifecycle state
*/
export type TCompanyStatus = 'planed' | 'founding' | 'active' | 'liquidation' | 'closed';
/**
* describes a company
*/
export interface ICompany {
name: string;
slogan?: string;
description?: string;
logoLink?: string;
foundedDate: general.IDate;
closedDate: general.IDate;
status: business.TCompanyStatus;
contact: business.IContact;
}

View File

@ -1,39 +1,60 @@
import { finance } from '../index.js';
import { business } from '../index.js';
import { finance, general } from "../index.js";
import { business } from "../index.js";
export type TContactSalutation = 'Mr' | 'Ms' | 'Mrs';
export type TSocialLinks = {
type: "facebook" | "twitter" | "linkedin" | string;
url: string;
};
export type TContactType = 'person' | 'company';
export type TRegistrationDetails = {
vatId: string;
registrationId: string;
registrationName: string;
};
export type TContactTitle = 'Doctor' | 'Professor';
export interface IContact {
// =======
// general
// =======
salutation?: TContactSalutation;
type: TContactType;
title?: TContactTitle;
relationship?: 'customer' | 'supplier' | 'partner' | 'employee' | 'other';
type TContactEnvelope<TYPE extends string, FIELDS> = {
type: TYPE;
name: string;
surname?: string;
legalEntity?: string;
address: business.IAddress;
description: string;
legalEntity?: string;
customerNumber?: string;
relationship?: "customer" | "supplier" | "partner" | "employee" | "other";
email?: string;
logoUrl?: string;
website?: string;
facebookUrl?: string;
twitterUrl?: string;
phone?: string;
fax?: string;
// =========
// financial
// =========
vatId?: string;
logoUrl?: string;
website?: string;
socials?: TSocialLinks[];
sepaConnection?: finance.ISepaConnection;
}
} & FIELDS;
export type TPerson = TContactEnvelope<
"person",
{
surname: string;
salutation: "Mr" | "Ms" | "Mrs";
sex: "male" | "female" | "other";
title: "Doctor" | "Professor";
registrationDetails?: TRegistrationDetails;
legalProxyFor?: {
type: "self" | "other";
contact?: TContact;
};
}
>;
export type TCompany = TContactEnvelope<
"company",
{
registrationDetails: TRegistrationDetails;
foundedDate: general.IDate;
closedDate: general.IDate;
status: "planned" | "founding" | "active" | "liquidation" | "closed";
}
>;
export type TContact = TPerson | TCompany;

View File

@ -1,20 +1,157 @@
import * as database from '../database/index.js';
import { type IPerson } from './person.js';
import * as database from "../database/index.js";
import { business } from "../index.js";
export interface IContract {
parties: {
signingOrder: number;
referencedAs: string;
person: IPerson;
role: 'signer' | 'cc';
signature: {
given: boolean;
timestamp?: number;
/**
* Represents a paragraph or section in a contract.
*/
export type TContractParagraph = {
id: string;
title?: string;
content: string; // Markdown formatted text
order: number;
type: "heading" | "clause" | "subclause" | "definition" | "exhibit";
isRequired: boolean;
metadata?: {
applicableJurisdictions?: string[];
tags?: string[];
lastModified?: number;
versionId?: string;
};
};
/**
* Contract party with signature information.
*/
export type TContractParty = {
signingOrder: number;
referencedAs: string;
person: business.TPerson;
role: "signer" | "cc" | "witness";
signature: {
given: boolean;
timestamp?: number;
location?: string;
ip?: string;
verifications?: any[];
};
};
/**
* Contract attachment like exhibits, appendices.
*/
export type TContractAttachment = {
id: string;
title: string;
type: "exhibit" | "appendix" | "schedule";
fileReference?: string;
content?: string; // Markdown or reference
};
/**
* Base envelope type for all contract types, extending the common document type.
*/
export type TContractEnvelope<TYPE extends string, FIELDS> = business.TDocumentEnvelope<
TYPE,
{
// Contract-specific dates
effectiveDate: number;
expirationDate?: number;
// Contract-specific status
status: "draft" | "negotiation" | "active" | "expired" | "terminated" | "renewed";
// Parties (multiple, without sender/recipient distinction)
parties: TContractParty[];
// Structured content
paragraphs: TContractParagraph[];
// Additional attachments
attachments?: TContractAttachment[];
} & FIELDS
>;
/**
* Employment contract specific type.
*/
export type TEmploymentContract = TContractEnvelope<
"employment",
{
employmentTerms: {
startDate: number;
position: string;
compensationDetails: string;
workingHours?: string;
location?: string;
ip?: string;
verifications?: [];
probationPeriod?: {
durationInMonths: number;
terms?: string;
};
};
}[];
contractTextMarkdown: string;
actions: database.IObjectAction[];
}
}
>;
/**
* Non-disclosure agreement specific type.
*/
export type TNDAContract = TContractEnvelope<
"nda",
{
confidentialityTerms: {
duration: number; // In months
scope: string;
exclusions?: string[];
};
}
>;
/**
* Service agreement specific type.
*/
export type TServiceContract = TContractEnvelope<
"service",
{
serviceTerms: {
scope: string;
deliverables: string[];
timeline?: {
milestones: {
description: string;
dueDate: number;
}[];
};
paymentTerms: string;
};
}
>;
/**
* Real estate lease agreement specific type.
*/
export type TLeaseContract = TContractEnvelope<
"lease",
{
propertyDetails: {
address: business.IAddress;
propertyType: string;
areaSize?: number;
areaSizeUnit?: string;
};
leaseTerms: {
rentAmount: number;
rentCurrency: string;
paymentFrequency: "monthly" | "quarterly" | "annually";
depositAmount?: number;
utilities?: string[];
};
}
>;
/**
* Union type for all contract types.
*/
export type TContract =
| TEmploymentContract
| TNDAContract
| TServiceContract
| TLeaseContract;

107
ts/business/document.ts Normal file
View File

@ -0,0 +1,107 @@
import * as database from "../database/index.js";
import * as business from "./index.js";
/**
* Base type for common document properties across different document types.
*/
export type TDocumentEnvelope<TYPE extends string, FIELDS> = {
/**
* Document type identifier
*/
type: TYPE;
/**
* Unique identifier for the document
*/
id: string;
/**
* Document creation/issuance date as a Unix timestamp
*/
date: number;
/**
* Document status in its lifecycle
*/
status: string;
/**
* Version information for the document
*/
versionInfo: {
/**
* Should follow semVer format
*/
version: string;
/**
* Type of version (draft vs final)
*/
type: "draft" | "final";
/**
* When this version was last modified
*/
lastModified?: number;
/**
* Version history for tracking changes
*/
history?: {
version: string;
modifiedAt: number;
modifiedBy?: string;
changeDescription?: string;
}[];
};
/**
* Primary language of the document
*/
language: string;
/**
* The text displayed at the top of the document, often a greeting or introduction
*/
topText?: string;
/**
* The text displayed at the bottom of the document, often a signature or conclusion
*/
bottomText?: string;
/**
* Formatting/branding information
*/
appearance?: {
/**
* URL to the logo to be displayed on the document
*/
logoUrl?: string;
/**
* Primary color for document styling
*/
accentColor?: string;
/**
* Font family for the document
*/
fontFamily?: string;
};
/**
* References to PDF versions of the document
*/
pdf?: business.IPdf;
/**
* PDF attachments are additional PDFs attached to the document
*/
pdfAttachments?: business.IPdf[];
/**
* Track document lifecycle actions
*/
objectActions?: database.IObjectAction[];
} & FIELDS;

View File

@ -1,8 +1,7 @@
export * from './address.js';
export * from './company.js';
export * from './contact.js';
export * from './document.js';
export * from './job.js';
export * from './letter.js';
export * from './pdf.js';
export * from './person.js';
export * from './project.js';

View File

@ -1,18 +1,17 @@
import * as finance from '../finance/index.js';
import { type ICompany } from './company.js';
import { type IContact } from './contact.js';
import * as finance from "../finance/index.js";
import { type TContact } from "./contact.js";
export class IJob {
type: 'contract' | 'employment';
type: "contract" | "employment";
techTags?: string[];
qualificationTags?: string[];
languages?: {
name: string;
level: 'basic' | 'intermediate' | 'advanced' | 'native';
level: "basic" | "intermediate" | "advanced" | "native";
}[];
name: string;
description: string;
monthlyTotal: number;
currency: finance.TCurrency;
from: ICompany;
contact: IContact;
from: TContact;
contact: TContact;
}

View File

@ -1,36 +1,65 @@
import * as business from './index.js';
import * as finance from '../finance/index.js';
import * as database from '../database/index.js';
export interface ILetter {
versionInfo: {
type: 'draft' | 'final';
import * as business from "./index.js";
import * as finance from "../finance/index.js";
/**
* Letter-specific envelope extending the base document type
*/
export type TLetterEnvelope<TYPE extends string, FIELDS> = business.TDocumentEnvelope<
TYPE,
{
/**
* should follow semVer
* The incident or case ID this letter relates to
*/
version: string;
};
incidenceId: string;
type: 'invoice' | 'notice' | 'warning' | 'verification' | 'contract';
date: number;
from: business.IContact;
to: business.IContact;
legalContact: business.IContact;
logoUrl: string;
subject: string;
accentColor?: string;
needsCoverSheet: boolean;
content: {
letterData: ILetter;
textData: string[];
invoiceData?: finance.IInvoice;
contractData?: {
id: string;
contractDate: number;
incidenceId: string;
/**
* The sender of the letter
*/
from: business.TContact;
/**
* The recipient of the letter
*/
to: business.TContact;
/**
* The legal contact is the contact that is responsible for the letter
* this is often the same as the from contact, but not always
*/
legalContact?: business.TContact;
/**
* Subject line of the letter
*/
subject: string;
/**
* Cover sheet configuration for the letter
*/
coverSheet?: {
enabled: boolean;
coverSheetText: string;
/**
* if true, the cover sheet will be marked as confidential
* hinting that only authorized persons should handle the letter
*/
confidential: boolean;
};
timesheetData: string;
}
pdf?: business.IPdf;
pdfAttachments: business.IPdf[];
language: string;
objectActions: database.IObjectAction[];
}
} & FIELDS
>;
export type TLetterSimple = TLetterEnvelope<"simple", {}>;
export type TLetter = TLetterSimple;
// type: "invoice" | "notice" | "warning" | "verification" | "contract";
/* content: {
textData: string[];
invoiceData?: finance.IInvoice;
contractData?: {
id: string;
contractDate: number;
};
timesheetData: string;
}; */

View File

@ -1,12 +0,0 @@
import { type IContact } from './contact.js';
export interface IPerson {
title: string;
name: string;
surname: string;
sex: 'male' | 'female' | 'queer';
legalProxyFor?: {
type: 'self' | 'other';
contact?: IContact;
};
}

View File

@ -13,5 +13,5 @@ export interface IVoucher {
date: Date;
description: string;
expenseItems: IExpenseItem[];
contactRef: business.IContact;
contactRef: business.TContact;
}

View File

@ -3,7 +3,7 @@ import type { TCurrency } from './currency.js';
export type TInvoiceStatus = 'draft' | 'invoice' | 'paid' | 'refunded';
export interface IInvoiceItem {
export type TInvoiceItem = {
position: number;
name: string;
articleNumber?: string;
@ -13,30 +13,50 @@ export interface IInvoiceItem {
vatPercentage: number;
}
export interface IInvoice {
id: string;
billedBy: business.IContact;
billedTo: business.IContact;
type: 'creditnote' | 'debitnote';
status: TInvoiceStatus;
items: IInvoiceItem[];
periodOfPerformance?: {
from: number;
to: number;
};
deliveryDate?: number;
dueInDays: number;
reverseCharge: boolean;
printResult?: {
pdfBufferString: string;
totalNet: number;
totalGross: number;
vatGroups: {
percentage: number;
items: IInvoiceItem[];
export type TInvoiceEnvelope<TYPE extends 'creditnote' | 'debitnote', FIELDS> = business.TLetterEnvelope<
'invoice',
{
invoiceId: string;
status: TInvoiceStatus;
type: TYPE;
items: TInvoiceItem[];
periodOfPerformance?: {
from: number;
to: number;
};
};
notes: string[];
paymentOptions?: finance.IPaymentOptionInfo;
currency: TCurrency;
}
deliveryDate?: number;
dueInDays: number;
reverseCharge: boolean;
/**
* buyer reference is an optional field, that helps the buyer to identify the invoice
*/
buyerReference?: string;
/**
* also a kind of reference, esspecially needed for circular xinvoice support.
*/
electronicAddress?: {
scheme: string;
value: string;
};
printResult?: {
pdfBufferString: string;
totalNet: number;
totalGross: number;
vatGroups: {
percentage: number;
items: TInvoiceItem[];
};
};
notes: string[];
paymentOptions?: finance.IPaymentOptionInfo;
currency: TCurrency;
} & FIELDS
>;
export type TCreditNote = TInvoiceEnvelope<'creditnote', {}>;
export type TDebitNote = TInvoiceEnvelope<'debitnote', {}>;
export type TInvoice = TCreditNote | TDebitNote;
// Legacy type for backward compatibility
export interface IInvoiceItem extends TInvoiceItem {}

View File

@ -1,6 +1,6 @@
export interface IReverseProxyConfig {
destinationIp: string;
destinationPort: string;
destinationIps: string[];
destinationPorts: number[];
hostName: string;
privateKey: string;
publicKey: string;

View File

@ -1,17 +1,17 @@
import { type ICompany } from "../business/company.js";
import type { TCompany } from "../business/contact.js";
export interface IProduct {
name: string;
slogan: string;
description: string;
os: 'web-based',
category: 'Business Application',
os: "web-based";
category: "Business Application";
offers: any[];
features: IProductFeature[];
landingPage: string;
appLink: string;
logoLink: string;
publisher?: ICompany;
publisher?: TCompany;
}
export interface IProductFeature {