Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 96 additions & 74 deletions lib/AppInfo/Application.php

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions lib/Controller/ChatStreamController.php
Original file line number Diff line number Diff line change
Expand Up @@ -411,9 +411,10 @@ private function safeShutdown(bool $rollback): void
if ($this->db->inTransaction() === true) {
if ($rollback === true) {
$this->db->rollBack();
} else {
$this->db->commit();
return;
}

$this->db->commit();
}
} catch (Throwable $e) {
$this->logger->warning(
Expand Down
4 changes: 2 additions & 2 deletions lib/Controller/OrganisationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1169,10 +1169,10 @@ public function activate(string $uuid): JSONResponse
if ($status === TenantLifecycleService::STATUS_PROVISIONING) {
$userId = \OC::$server->get(\OCP\IUserSession::class)->getUser()?->getUID() ?? 'admin';
$result = $this->tenantLifecycleService->provision($organisation, $userId);
} else {
$result = $this->tenantLifecycleService->reactivate($organisation);
return new JSONResponse(data: $result, statusCode: Http::STATUS_OK);
}

$result = $this->tenantLifecycleService->reactivate($organisation);
return new JSONResponse(data: $result, statusCode: Http::STATUS_OK);
} catch (Exception $e) {
$statusCode = $e->getCode() >= 400 ? $e->getCode() : Http::STATUS_INTERNAL_SERVER_ERROR;
Expand Down
28 changes: 0 additions & 28 deletions lib/Db/AuditTrailMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ public function findByImportJobId(string $importJobId, ?string $action='create')
return $this->findEntities(query: $qb);
}//end findByImportJobId()



/**
* Finds an audit trail by id
*
Expand All @@ -182,7 +180,6 @@ public function find(int $id): AuditTrail
return $this->findEntity(query: $qb);
}//end find()


/**
* Find all audit trails with filters and sorting
*
Expand Down Expand Up @@ -324,9 +321,6 @@ function ($key) {
return $this->findEntities(query: $qb);
}//end findAll()




/**
* Creates an audit trail for object changes
*
Expand Down Expand Up @@ -632,7 +626,6 @@ private function readProcessingActivityFromRegister($registerId): ?string

}//end readProcessingActivityFromRegister()


/**
* Get audit trails for an object until a specific point or version
*
Expand Down Expand Up @@ -703,7 +696,6 @@ public function findByObjectUntil(int $objectId, string $objectUuid, $until=null
return $this->findEntities(query: $qb);
}//end findByObjectUntil()


/**
* Check if a string is a semantic version
*
Expand All @@ -716,7 +708,6 @@ private function isSemanticVersion(string $version): bool
return (preg_match('/^\d+\.\d+\.\d+$/', $version) === 1);
}//end isSemanticVersion()


/**
* Revert an object to a previous state
*
Expand Down Expand Up @@ -766,7 +757,6 @@ public function revertObject($identifier, $until=null, bool $overwriteVersion=fa
return $revertedObject;
}//end revertObject()


/**
* Helper function to revert changes from an audit trail entry
*
Expand All @@ -792,7 +782,6 @@ private function revertChanges(ObjectEntity $object, AuditTrail $audit): void
}
}//end revertChanges()


/**
* Get statistics for audit trails with optional filtering
*
Expand Down Expand Up @@ -885,7 +874,6 @@ public function getStatistics(?int $registerId=null, ?int $schemaId=null, array
}//end try
}//end getStatistics()


/**
* Updates an entity in the database
*
Expand All @@ -907,7 +895,6 @@ public function update(Entity $entity): AuditTrail
return parent::update(entity: $entity);
}//end update()


/**
* Get chart data for audit trail actions over time
*
Expand Down Expand Up @@ -1012,7 +999,6 @@ function ($data) use ($action) {
}//end try
}//end getActionChartData()


/**
* Get detailed statistics for audit trails including action counts within timeframe
*
Expand Down Expand Up @@ -1113,7 +1099,6 @@ public function getDetailedStatistics(?int $registerId=null, ?int $schemaId=null
}//end try
}//end getDetailedStatistics()


/**
* Get action distribution data with percentages
*
Expand Down Expand Up @@ -1192,7 +1177,6 @@ public function getActionDistribution(?int $registerId=null, ?int $schemaId=null
}//end try
}//end getActionDistribution()


/**
* Get most active objects based on audit trail activity
*
Expand Down Expand Up @@ -1268,7 +1252,6 @@ public function getMostActiveObjects(?int $registerId=null, ?int $schemaId=null,
}//end try
}//end getMostActiveObjects()


/**
* Clear expired logs from the database
*
Expand Down Expand Up @@ -1317,7 +1300,6 @@ public function clearLogs(): bool
}//end try
}//end clearLogs()


/**
* Clear all audit trail logs (not just expired ones)
*
Expand Down Expand Up @@ -1358,9 +1340,6 @@ public function clearAllLogs(): bool
}//end try
}//end clearAllLogs()




/**
* Set expiry dates for audit trails based on retention period in milliseconds
*
Expand Down Expand Up @@ -1411,7 +1390,6 @@ public function setExpiryDate(int $retentionMs): int
}//end try
}//end setExpiryDate()


/**
* Get audit trail statistics grouped by schema for multiple schemas in a single query
*
Expand Down Expand Up @@ -1479,7 +1457,6 @@ public function getStatisticsGroupedBySchema(array $schemaIds): array
}//end try
}//end getStatisticsGroupedBySchema()


/**
* Create a custom audit trail entry for archival operations.
*
Expand Down Expand Up @@ -1522,7 +1499,6 @@ public function createAuditTrailEntry(
return $this->insert(entity: $auditTrail);
}//end createAuditTrailEntry()


/**
* Get processing activities from audit trail entries.
*
Expand Down Expand Up @@ -1577,7 +1553,6 @@ public function getProcessingActivities(?string $organisationId=null): array
return array_values($activities);
}//end getProcessingActivities()


/**
* Find audit trail entries by identifier.
*
Expand Down Expand Up @@ -1616,7 +1591,6 @@ public function findByIdentifier(string $identifier): array
return $grouped;
}//end findByIdentifier()


/**
* Find audit trail entries by the actor (user UID) that produced them.
*
Expand Down Expand Up @@ -1693,6 +1667,4 @@ public function findByActor(
'total' => (int) ($row['total_count'] ?? 0),
];
}//end findByActor()


}//end class
8 changes: 5 additions & 3 deletions lib/Db/MagicMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,7 @@ private function searchAcrossMultipleTablesWithUnion(array $query, array $regist
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
* @SuppressWarnings(PHPMD.UnusedLocalVariable) `$_` is the conventional ignore name in the metadata-column foreach
*/
private function buildUnionSelectPart(
string $tableName,
Expand All @@ -1299,12 +1300,13 @@ private function buildUnionSelectPart(
// Cast to text for UNION type compatibility (some columns are jsonb, others text).
$metadataColumns = $this->getMetadataColumns();
$selectColumns = [];
foreach ($metadataColumns as $metaCol => $metaDef) {
foreach ($metadataColumns as $metaCol => $_) {
if ($this->columnExistsInTable(tableName: $tableName, columnName: $metaCol) === true) {
$selectColumns[] = "{$metaCol}::text AS {$metaCol}";
} else {
$selectColumns[] = "NULL::text AS {$metaCol}";
continue;
}

$selectColumns[] = "NULL::text AS {$metaCol}";
}

/*
Expand Down
11 changes: 6 additions & 5 deletions lib/Db/MagicMapper/MagicSearchHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -497,11 +497,12 @@ private function buildSearchConditionSql(
if ($isPostgres === true) {
// ILIKE is always case-insensitive on PostgreSQL.
$searchConditions[] = "{$quotedCol}::text ILIKE {$likePattern}";
} else {
// CAST + LOWER on both sides keeps MySQL case-insensitive regardless of
// collation (e.g., utf8mb4_bin), matching applyFullTextSearch().
$searchConditions[] = "LOWER(CAST({$quotedCol} AS CHAR)) LIKE LOWER({$likePattern})";
}//end if
continue;
}

// CAST + LOWER on both sides keeps MySQL case-insensitive regardless of
// collation (e.g., utf8mb4_bin), matching applyFullTextSearch().
$searchConditions[] = "LOWER(CAST({$quotedCol} AS CHAR)) LIKE LOWER({$likePattern})";
}//end if
}//end foreach

Expand Down
23 changes: 12 additions & 11 deletions lib/Db/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -1696,17 +1696,18 @@ private function validateConfigurationArray(array $configuration): array
if (str_starts_with((string) $key, 'x-openregister-') === true) {
if (in_array((string) $key, self::ANNOTATION_VOCABULARY, true) === true) {
$validatedConfig[$key] = $value;
} else {
// R07: track unknown `x-openregister-*` keys (almost
// always typos like `x-openregister-lifecycl`) so
// SchemaMapper can log them via its structured
// logger after save. The entity has no DI surface
// for a logger and the ADR added in F06 bans the
// `\OC::$server` static accessor — collecting on
// the entity and bridging through the mapper is
// the cleanest path that still surfaces a signal.
$this->droppedAnnotationKeys[] = (string) $key;
}//end if
continue;
}

// R07: track unknown `x-openregister-*` keys (almost
// always typos like `x-openregister-lifecycl`) so
// SchemaMapper can log them via its structured
// logger after save. The entity has no DI surface
// for a logger and the ADR added in F06 bans the
// `\OC::$server` static accessor — collecting on
// the entity and bridging through the mapper is
// the cleanest path that still surfaces a signal.
$this->droppedAnnotationKeys[] = (string) $key;
}//end if
}//end foreach

Expand Down
6 changes: 5 additions & 1 deletion lib/Listener/NotifyPushListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ public function handle(Event $event): void
} else if ($event instanceof ObjectDeletedEvent) {
$action = 'delete';
$object = $event->getObject();
} else {
}

if (isset($action) === false || isset($object) === false) {
return;
}

Expand Down Expand Up @@ -332,6 +334,8 @@ public static function resetStaticState(): void
* @return void
*
* @spec openspec/changes/add-live-updates/tasks.md#task-4
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter) Permission handler retained on the signature for upcoming per-user batch routing
*/
public static function flushBatch(object $queue, PermissionHandler $permHandler): void
{
Expand Down
11 changes: 7 additions & 4 deletions lib/Service/Chat/ResponseGenerationHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use OCA\OpenRegister\Db\Agent;
use OCA\OpenRegister\Service\SettingsService;
use OCA\OpenRegister\Service\Chat\ToolManagementHandler;
use OCA\OpenRegister\Tool\StreamingToolInstanceWrapper;
use Psr\Log\LoggerInterface;
use LLPhant\Chat\OpenAIChat;
use LLPhant\Chat\OllamaChat;
Expand All @@ -42,6 +43,7 @@
use LLPhant\OllamaConfig;
use LLPhant\Exception\MissingFeatureException;
use Psr\Http\Message\StreamInterface;
use ReflectionClass;

/**
* ResponseGenerationHandler
Expand Down Expand Up @@ -318,9 +320,10 @@ public function generateResponse(
foreach ($cnAiContext as $key => $value) {
if (is_scalar($value) === true) {
$systemPrompt .= "- {$key}: ".(string) $value."\n";
} else {
$systemPrompt .= "- {$key}: ".json_encode($value, JSON_UNESCAPED_SLASHES)."\n";
continue;
}

$systemPrompt .= "- {$key}: ".json_encode($value, JSON_UNESCAPED_SLASHES)."\n";
}
}

Expand Down Expand Up @@ -506,7 +509,7 @@ private function wrapToolsForStreaming(array $functionInfoObjects, ?StreamYieldC

foreach ($functionInfoObjects as $fi) {
if (is_object($fi->instance) === true) {
$fi->instance = new \OCA\OpenRegister\Tool\StreamingToolInstanceWrapper(
$fi->instance = new StreamingToolInstanceWrapper(
wrapped: $fi->instance,
channel: $channel
);
Expand Down Expand Up @@ -583,7 +586,7 @@ private function invokeChat(
private function chatHasTools(OpenAIChat|OllamaChat $chat): bool
{
try {
$refl = new \ReflectionClass($chat);
$refl = new ReflectionClass($chat);
if ($refl->hasProperty(name: 'tools') === false) {
return false;
}
Expand Down
4 changes: 3 additions & 1 deletion lib/Service/Configuration/ImportHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2695,7 +2695,9 @@ private function autoCreateRegisterIfApplication(
'unionSchemaIds' => $unionSchemaIds,
]
);
} else {
}//end if

if ($register === null) {
// Fresh insert: derive a new Register entity.
$register = $this->registerMapper->createFromArray(
object: [
Expand Down
5 changes: 3 additions & 2 deletions lib/Service/Integration/BuiltinProviders/TasksProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

namespace OCA\OpenRegister\Service\Integration\BuiltinProviders;

use RuntimeException;
use OCA\OpenRegister\Db\RegisterMapper;
use OCA\OpenRegister\Db\SchemaMapper;
use OCA\OpenRegister\Exception\NotImplementedException;
Expand Down Expand Up @@ -219,7 +220,7 @@ public function create(string $register, string $schema, string $objectId, array
);

if ($task === null) {
throw new \RuntimeException('TaskService::createTask returned null — calendar invalid or auth failure.');
throw new RuntimeException('TaskService::createTask returned null — calendar invalid or auth failure.');
}

return $task;
Expand All @@ -242,7 +243,7 @@ public function update(string $register, string $schema, string $objectId, strin
$updated = $this->taskService->updateTask(calendarId: $calendarId, taskUri: $taskUri, data: $payload);

if ($updated === null) {
throw new \RuntimeException('TaskService::updateTask returned null — entity may not exist.');
throw new RuntimeException('TaskService::updateTask returned null — entity may not exist.');
}

return $updated;
Expand Down
Loading
Loading