# What the internal/application Package Handles in WeKnora: Business Logic and Service Layer

> Discover how the WeKnora internal/application package manages business logic, orchestrating wiki lifecycles, content ingestion, skill execution, and vector search operations.

- Repository: [Tencent/WeKnora](https://github.com/tencent/WeKnora)
- Tags: internals
- Published: 2026-09-13

---

**The `internal/application` package serves as the core business-logic layer of WeKnora, orchestrating wiki page lifecycles, content ingestion, tenant skill execution, and vector search operations while bridging HTTP handlers and data repositories.**

The `internal/application` package sits at the heart of the Tencent/WeKnora architecture, implementing the domain logic that powers the knowledge-base platform. Located between the API handlers in `internal/api` and the data-access layer in `internal/application/repository`, this package encapsulates everything from CRUD operations on wiki pages to LLM pipeline orchestration. Understanding its structure is essential for developers extending WeKnora’s capabilities or debugging service-level issues.

## Core Responsibilities of the internal/application Package

The package organizes its functionality into cohesive service modules that handle distinct domain concerns. Each service operates as a facade over lower-level repositories, enforcing business rules and transaction boundaries.

### Wiki Page Orchestration and Lifecycle Management

At the center of the package, [`internal/application/service/wiki_page.go`](https://github.com/Tencent/WeKnora/blob/main/internal/application/service/wiki_page.go) defines the `wikiPageService` struct, which implements the full CRUD lifecycle for wiki content. This service handles **versioning**, **bidirectional link maintenance**, and **graph generation** for knowledge bases.

Key capabilities include:

- **CreatePage** and **UpdatePage**: Persist wiki content while parsing internal links and maintaining slug integrity.
- **GetGraph**: Generate subgraph views of the knowledge base with BFS ego-mode traversal (implemented via `bfsEgoSlugs`).
- **RebuildLinks**: Repair and synchronize bidirectional wiki links after content changes.
- **Content normalization**: Utilities like `normalizeSlug` and `rewriteDeadWikiLinks` ensure consistent URL slugs and repair broken references.

### Content Ingest Pipeline

The ingest subsystem processes bulk wiki imports through a coordinated pipeline spread across [`wiki_ingest.go`](https://github.com/Tencent/WeKnora/blob/main/wiki_ingest.go), [`wiki_ingest_dedup.go`](https://github.com/Tencent/WeKnora/blob/main/wiki_ingest_dedup.go), and [`wiki_ingest_cite.go`](https://github.com/Tencent/WeKnora/blob/main/wiki_ingest_cite.go). This pipeline handles **taxonomy extraction**, **deduplication**, **citation processing**, and **dead-link repair** when migrating existing content into WeKnora.

### Tenant Skill Execution Engine

WeKnora supports per-tenant plugins called "skills" that augment the knowledge base or run custom LLM pipelines. The [`internal/application/service/tenant_skill_service.go`](https://github.com/Tencent/WeKnora/blob/main/internal/application/service/tenant_skill_service.go) file implements the **skill lifecycle management**, including:

- Verification and installation of skill packages.
- Runtime execution control via `RunSkill`.
- Cleanup and resource isolation between tenants.

This allows individual knowledge bases to load custom logic without affecting the core system stability.

### Vector Store Abstraction for Semantic Search

The [`vectorstore.go`](https://github.com/Tencent/WeKnora/blob/main/vectorstore.go) file provides a unified interface for semantic retrieval via the `VectorStoreService`. It abstracts multiple backends—such as OpenSearch and SSRF-safe SQLite—behind methods like `AddEmbedding` and `Search`. This abstraction lets the rest of the application perform vector operations without coupling to specific storage engines.

### Web Search Integration

To augment LLM prompts with real-time data, [`web_search_provider.go`](https://github.com/Tencent/WeKnora/blob/main/web_search_provider.go) encapsulates remote web-search providers. It handles provider authentication, result fetching, and content filtering before injecting search context into chat pipelines.

### Access Control and Knowledge Base Sharing

Security logic resides in [`internal/application/access/ownership.go`](https://github.com/Tencent/WeKnora/blob/main/internal/application/access/ownership.go) and related `kb_*` files. These modules enforce **ownership verification**, **write-permission checks**, and **sharing mechanics** before any service modifies knowledge base data. This ensures that multi-tenant isolation and collaboration rules are applied consistently across all operations.

### User and Tenant Utilities

Supporting infrastructure for authentication and configuration lives in files like [`user_env.go`](https://github.com/Tencent/WeKnora/blob/main/user_env.go), [`user_oidc_security.go`](https://github.com/Tencent/WeKnora/blob/main/user_oidc_security.go), and [`user_admin_create.go`](https://github.com/Tencent/WeKnora/blob/main/user_admin_create.go). These handle **JWT validation**, **OIDC verification**, **environment-variable resolution**, and **tenant-scoped context** propagation throughout the service layer.

### Chat Pipeline Helpers

The `chat_pipeline/` subdirectory contains specialized utilities for LLM workflows, including [`rerank.go`](https://github.com/Tencent/WeKnora/blob/main/rerank.go) for result reordering and [`memory_recall.go`](https://github.com/Tencent/WeKnora/blob/main/memory_recall.go) for conversational context retrieval. These helpers implement **query expansion**, **semantic reranking**, and **session memory** management to improve response quality.

## Key Source Files and Their Roles

Understanding the file layout helps navigate the codebase effectively:

- **[`service/wiki_page.go`](https://github.com/Tencent/WeKnora/blob/main/service/wiki_page.go)**: Central service for wiki CRUD, graph computation, and link management.
- **[`service/wiki_ingest.go`](https://github.com/Tencent/WeKnora/blob/main/service/wiki_ingest.go)**: Entry point for batch content ingestion and taxonomy processing.
- **[`service/tenant_skill_service.go`](https://github.com/Tencent/WeKnora/blob/main/service/tenant_skill_service.go)**: Coordination of plugin installation and execution.
- **[`service/vectorstore.go`](https://github.com/Tencent/WeKnora/blob/main/service/vectorstore.go)**: Abstraction over vector databases for embedding storage and similarity search.
- **[`service/web_search_provider.go`](https://github.com/Tencent/WeKnora/blob/main/service/web_search_provider.go)**: Integration layer for external search APIs.
- **[`access/ownership.go`](https://github.com/Tencent/WeKnora/blob/main/access/ownership.go)**: Domain-level permission checks and KB ownership logic.
- **[`service/user_env.go`](https://github.com/Tencent/WeKnora/blob/main/service/user_env.go)**: Configuration and context resolution for user sessions.
- **[`service/chat_pipeline/rerank.go`](https://github.com/Tencent/WeKnora/blob/main/service/chat_pipeline/rerank.go)**: Algorithms for reordering search results based on relevance.

## Practical Code Examples

The following snippets demonstrate typical interactions with the `internal/application` services.

### Creating a Wiki Page

```go
svc := NewWikiPageService(repo, chunkRepo, kbService, taskPendingRepo, redisClient)
ctx := types.WithWikiEditSource(context.Background(), types.WikiEditSourceUser)
page := &types.WikiPage{
    KnowledgeBaseID: "kb-123",
    Slug:            "example-page",
    Title:           "Example Page",
    Content:         "This is a [[linked-page]] in markdown.",
    PageType:        types.WikiPageTypeSummary,
}
created, err := svc.CreatePage(ctx, page)
if err != nil {
    // handle error
}
fmt.Println("Created page ID:", created.ID)

```

### Generating a Knowledge Graph

```go
graphReq := &types.WikiGraphRequest{
    KnowledgeBaseID: "kb-123",
    Mode:            types.WikiGraphModeOverview,
    Limit:           200,
}
graph, err := svc.GetGraph(context.Background(), graphReq)
if err != nil {
    // handle error
}
fmt.Printf("Graph contains %d nodes, %d edges\n", len(graph.Nodes), len(graph.Edges))

```

### Executing a Tenant Skill

```go
skillSvc := NewTenantSkillService(repo, taskPendingRepo, redisClient)
err := skillSvc.RunSkill(context.Background(), "kb-123", "my-skill-id")
if err != nil {
    // handle error
}

```

## Summary

- The `internal/application` package implements WeKnora’s **business-logic layer**, isolating domain rules from HTTP transport and data persistence.
- Core services manage **wiki page lifecycles**, **batch ingestion**, **tenant skill execution**, and **vector search** operations.
- **Access control** is enforced centrally through the `access/` subdirectory, ensuring secure multi-tenant operations.
- The package provides **abstractions** for web search and vector stores, allowing backend implementations to change without affecting API consumers.
- All service implementations reside in `internal/application/service/`, with clear separation between orchestration logic and repository concerns.

## Frequently Asked Questions

### What is the difference between `internal/application` and `internal/api` in WeKnora?

The `internal/api` package handles HTTP routing, request validation, and JSON serialization, while `internal/application` contains the **domain logic** that processes those requests. The API layer translates HTTP calls into service method invocations, and the application layer enforces business rules, coordinates transactions, and interacts with repositories. This separation ensures that core logic remains transport-agnostic and testable without HTTP dependencies.

### How does the internal/application package handle vector search?

The package exposes semantic search through [`service/vectorstore.go`](https://github.com/Tencent/WeKnora/blob/main/service/vectorstore.go), which defines the `VectorStoreService` interface with methods like `AddEmbedding` and `Search`. This service abstracts underlying storage engines—such as OpenSearch or SQLite—providing a unified API for the rest of the system. Callers simply invoke `Search` with a query embedding, and the service handles backend-specific query construction and result retrieval.

### Where are tenant skills defined and executed within the application layer?

Tenant skills are managed by [`service/tenant_skill_service.go`](https://github.com/Tencent/WeKnora/blob/main/service/tenant_skill_service.go). This service handles the **installation, validation, and runtime execution** of per-tenant plugins. The `RunSkill` method accepts a knowledge base ID and skill identifier, loads the appropriate plugin code in an isolated context, and executes it against the tenant’s data. This architecture allows custom extensions without modifying core WeKnora binaries.

### How is access control enforced in the internal/application package?

Access control logic resides in [`access/ownership.go`](https://github.com/Tencent/WeKnora/blob/main/access/ownership.go) and associated knowledge base permission files. Before executing destructive operations, services invoke ownership checks to verify that the requesting user has **write permissions** or **ownership rights** for the target knowledge base. These checks run after authentication (handled upstream) but before any repository modifications, ensuring consistent enforcement of multi-tenant security policies.