Changelog
What's new.
Every improvement to the platform, as it ships.
· kamo-marketing
Add /requests direct nav links, homepage section, and plan feature comparison row
- Header: Requests added as top-level direct link between Pricing and Company - Footer: Requests added to Product column for direct visibility - Pricing page: custom dev callout banner between bundles and feature comparison - Features page: feature requests callout before CTA - Homepage: new FeatureRequests section between Pricing and FAQ showing plan-tier access - JumpToBar: Requests jump link added between Pricing and FAQ - DB: FEATURE_REQUESTS seeded in Support category with per-plan text values (Free: Community vote, Starter: Vote & request, Business: Priority requests, Enterprise: Custom dev included) - KamoCRMPricingLoader: updated with FEATURE_REQUESTS feature definition and plan-feature mappings
· kamo-internal
Round-trip appConfigs + surface applied-model settings + private-org toggle
- BranchSetupManager: mapBackendModel now hydrates the persisted appConfigs returned by the backend (availability + allowedCommerceTypes per service type) instead of resetting them to NOT_AVAILABLE on load. Save payloads for both the child-model and master-model flows include appConfigs so the per-app availability and CRM commerce-type restrictions round-trip. Master model editor reuses mapBackendModel so it behaves identically. - useAppliedModel hook: expanded response type now carries the applied model's scalar settings (allowOwnersViewOtherOrgs, allowOwnersPrivateOrgs, allowSubChildOrgs, age ranges, identityProviderSetting, teamMemberPayFeesSetting), the appConfigs map, and orgIsPrivate — so any future editor (feature manager, OAuth config, commerce market) can gate uniformly without re-fetching. - Private-org toggle: new proxy route **************** (PATCH) and a visibility card surfaced on the branch-types tab, gated by allowOwnersPrivateOrgs. When enabled, other org owners won't see this org in listings. Optimistic UI reconciles against the next applied-model refresh.
· BillingService
Enforce team-member pay-fees setting at Stripe customer creation
Bumps kamo-shared-library dependency to 1.5.0 so BillingService can resolve the new AppliedModelEnforcementService, and wires team-member vs org pay-fees enforcement into **************** - teamMemberPayFeesSetting == NOT_AVAILABLE: creating a member-specific billing customer (self-pay) is rejected — the org must cover fees. - teamMemberPayFeesSetting == FORCE_ENABLE: creating an org-level customer that would cover team-member charges is rejected — team members must pay themselves. - OPTIONAL: either flow is permitted. Enforcement is best-effort when the org can't be resolved (tooling contexts, legacy data) — falls through to the legacy behavior instead of blocking.
· SecurityService
Wire applied-model enforcement across every controller
Every non-role setting on the applied security model is now enforced at the exact controller boundary it governs, and the scalar settings round-trip cleanly through the master/child model editors so the UI can gate on them. - **************** when branchTypeID is set, look up the branch type to derive the parent org; call assertSubChildOrgAllowed and assertAgeRangeAllowed for both member and team-member age slots before committing. New PATCH /{id}/visibility endpoint lets owners flip Organization.isPrivate, gated by assertCanSetPrivate. getAllOrganizations applies filterVisibleOrgsForViewer so results respect both allowOwnersViewOtherOrgs on the viewer's model and the isPrivate flag on candidates. - **************** call assertAppEnableAllowed / assertAppDisableAllowed so NOT_AVAILABLE apps can't be enabled and FORCE_ENABLED apps can't be disabled. - OAuthConfigController POST/PUT: assertCanManageIdentityProvider blocks provider CRUD when identityProviderSetting == NOT_AVAILABLE. - CommerceMarketController POST/PUT: assertCommerceTypeAllowed rejects a commerce type not listed in the model's appConfig for CRM. - SecurityModelController + MasterModelController: round-trip appConfigs through create/update payloads and the GET responses. New processAppConfigs helper accepts the list form used by the frontend editor. - AppliedModelController: response now includes the full scalar settings block (allowOwnersViewOtherOrgs, allowOwnersPrivateOrgs, allowSubChildOrgs, age ranges, identityProviderSetting, teamMemberPayFeesSetting) and the appConfigs map so frontend editors can gate uniformly. Also surfaces orgIsPrivate so the privacy toggle stays in sync.
· kamo-shared-library
Enforce every non-role setting on ChildOrgSecurityModel
Adds end-to-end enforcement for the remaining settings on an org's applied security model. Every setting that was previously only read (or dropped on save) now has a persistence path, a runtime enforcement helper, and a UI hook to consume it. Data layer: - Organization.isPrivate (boolean column, default false) — org's own visibility flag, set through the new MasterModelController-gated PATCH endpoint. - ServiceAvailabilityType enum (OPTIONAL_DEFAULT_ENABLED / OPTIONAL_DEFAULT_DISABLED / NOT_AVAILABLE / FORCE_ENABLED). - ChildOrgSecurityModelAppConfig entity + repo + service — persists per-app availability (and CRM's allowedCommerceTypes) previously dropped on save. - **************** round-trips the new entity. Runtime enforcement: - AppliedModelEnforcementService consolidates every check used by callers: assertSubChildOrgAllowed, assertAgeRangeAllowed, **************** isIdentityProviderRequired, assertCanSetPrivate, filterVisibleOrgsForViewer, assertTeamMemberCanSelfPayFees, isTeamMemberPayFeesForced / Blocked, assertAppEnableAllowed, assertAppDisableAllowed, getAppAvailability, getDefaultEnabledAppsForChild, assertCommerceTypeAllowed, getAllowedCommerceTypes. Null-safe: "no applied model" permits everything. - ChildOrgTemplateSeedingService extended to also seed OrgFeature rows from the parent's appConfig defaults (FORCE_ENABLED and OPTIONAL_DEFAULT_ENABLED) on new child orgs, so newly-provisioned orgs come up with the right default surface.
· kamo-internal
Lock mandatory system roles in member role-assignment UI
- PublicProvider: admit branchTypeID/masterModelID on the incoming organization payload so the branch-types tab can reliably gate the "Edit Master Model" button (previously relied on Jackson serialization flowing through the prop type check). - RolesPermissionsTab: the role checkbox grid now marks the required system role(s) as checked and disabled based on the member's type and owner flag: * Member-typed members: "Members" is required. * Team-Member-typed members: "Team Members" is required. * Team-Member-typed owners: "Administrator (Full Access)" is additionally required. A "Required" chip and explanatory hint make the constraint visible to the editor. Attempting to toggle a mandatory role is a no-op; the backend reconciliation in MemberSecurityController would re-add it anyway.
· SecurityService
Enforce system-role assignment and auto-admin for team-member owners
MemberSecurityController now enforces the three assignment invariants defined in the brainstorm spec: - saveMemberSecurity: before persisting the caller's requested roleIds, augments the set with the mandatory system role(s) based on member type: Member-typed members always get roleMemberID; Team-Member-typed members always get roleTeamMemberID; Team-Member owners additionally always get roleAdminID. LinkedHashSet preserves caller ordering while deduping. - updateMemberAccess: when the owner flag toggles, the Administrator role is added or removed on the team-member to keep role assignments in sync with ownership. Rights-applied recalculation runs in the same transaction so downstream reads see the updated effective permissions immediately.
· kamo-shared-library
Apply template force rules and DEFAULT fallback to member rights resolution
**************** now overlays the applied model's 4 default-role templates on top of the existing cascade (org roles → department → job title → member): - Role-type-specific FORCE_GRANTED/FORCE_NUKE wins over all cascade levels. The template is chosen by member type: team-member owners use ADMINISTRATOR, team-members use TEAM_MEMBER, plain members use MEMBER. - DEFAULT template FORCE values win over cascade when the role-type template has no force rule for that right (per Q7 precedence). - DEFAULT non-force values (GRANTED/NUKE) act as last-line-of-defense for rights that resolved to NOT_SPECIFIED after the full cascade. AppliedModelResolverService is injected as @Autowired(required=false) so existing unit-test wirings that only construct the two constructor-mandatory repositories continue to work, degrading to the legacy no-force-rules path.
· kamo-internal
Add master model editor, role templates, and force-rule gating
Surfaces the new branch-type security model in the UI: - branch-types tab gains an "Edit Master Model" button (hidden when the org has a branchTypeID assigned) that opens the model editor in master mode: no name field, no branch-types chip, save hits /master-model. - Model editor (both add-child-model and edit-master-model) gains a new "Default Security Roles" section after "Allowed Apps", with tabs for Administrator / Team Member / Member / DEFAULT and 5-value settings (FORCE_GRANTED, GRANTED, NOT_SPECIFIED, FORCE_NUKE, NUKE). - New useAppliedModel() hook fetches /api/security/applied-model once and exposes isForced(rightName, roleType) for consuming editors. - Security roles, departments, job titles, and per-member roles-permissions pages hide rights force-locked by the applicable templates: * security-roles: system roles use their matching template + DEFAULT; custom roles use DEFAULT only (Q11 answer A). * departments + job-titles: DEFAULT only (non-role-specific). * member page: member-type template (TEAM_MEMBER vs MEMBER) + DEFAULT (Q8 answer C, type-first evaluation order). New proxy routes: /api/security/master-model (GET/PUT), /api/security/applied-model (GET).
· SecurityService
Master-model + applied-model endpoints and template-aware org seeding
Adds the controllers that surface the new branch-type security flow: - /api/security/master-model (GET/PUT) manages the current org's master model; only writeable when Organization.branchTypeID is null. - /api/security/applied-model (GET) resolves which model governs this org and returns per-template force-rule maps for frontend gating. - SecurityModelController round-trips the 4 default-role templates as part of its existing create/update payloads. - OrganizationController propagates the new branchTypeID from the request body and seeds the new org's 3 system roles from the applied model's templates via ChildOrgTemplateSeedingService.
· kamo-shared-library
Add master model, default role templates, and applied-model resolver
Introduces the data layer for the new branch-type security model flow: - Organization gains nullable branchTypeID and masterModelID columns. - New RoleRightTemplateSettingType enum with 5 values (FORCE_GRANTED, GRANTED, NOT_SPECIFIED, FORCE_NUKE, NUKE) for template-layer settings. - New DefaultRoleType enum (ADMINISTRATOR, TEAM_MEMBER, MEMBER, DEFAULT) for the 4 role templates attached to each ChildOrgSecurityModel. - New entities **************** and **************** plus their repos, service, and DTOs. - AppliedModelResolverService resolves the model that governs a given org (branchType-inherited or master) and exposes force-rule lookups. - ChildOrgTemplateSeedingService seeds new child orgs' 3 system roles with GRANTED/NUKE values from the applied model's templates; force values stay in the template and are enforced at runtime. End-user OrgRoleRight continues to use the 3-value RoleRightSettingType — force values are strictly a template-layer concept.
· kamo-internal
Add branch type chip-input field to security model editor
- BranchTypeChipField with colored dot toggle, edit-on-click label, and X delete - BranchTypeEditDialog for name/description editing - Autocomplete dropdown pulls from GET /api/security/branch-types, excludes current model types, shows source model for cross-model types - handleSaveModel sends branchTypes and deletedBranchTypeIds in PUT/POST payload - List table gets Branch Types column with colored dot chips - loadModels maps branchTypes from backend response
· kamo-login
Remove MANAGE_USERS right from RoleRightType
· kamo-register
Remove MANAGE_USERS right from RoleRightType
· kamo-internal
Remove MANAGE_USERS right from all frontend references
· kamo-shared-library
Remove MANAGE_USERS right (id=19) from RoleRightType enum
· kamo-internal
Add branch-types security API route
· SecurityService
Wire branch types into security model CRUD endpoints
· kamo-shared-library
Expand ChildOrgSecurityModelDTO with full fields and branchTypes
· kamo-shared-library
Add OrgBranchTypeService
· kamo-shared-library
Add OrgBranchTypeRepository
· kamo-shared-library
Add OrgBranchTypeDTO
· kamo-shared-library
Add OrgBranchType entity
· kamo-internal
Update BranchSetupManager subtitle to reference dynamic branch type label
· kamo-internal
Rename Branch Setup tab to dynamic {branchLabel} Types and update URL to branch-types
· kamo-login
Reset Capcha *** after every failed login attempt
Users must re-verify they are human after each incorrect password. Calls widget.reset() and clears CapchaVerified/payload state on both credential failures and network errors.
· EmailService
Auto-inject logoUrl, logoSimpleUrl, and orgName variables at send time
EmailTemplateService now merges base variables (logoUrl, logoSimpleUrl, orgName) derived from the org's primary domain before rendering, so all transactional templates can reference {{logoUrl}} and {{logoSimpleUrl}} without callers needing to pass them explicitly. Caller-supplied vars still take precedence.
· kamo-internal
Add permission gates for user-level fields and password change section in MyAccountTab
· kamo-internal
Add access gate and MANAGE_MEMBER_SECURITY tab guard to member settings page
· kamo-internal
Add change-password Next.js API proxy route

Your universe is waiting.
Start free in minutes. Add products whenever you are ready — no migration, no new logins.
Free forever — no credit card required