Skip to content

issue 17 carinfo contract fix#25

Merged
Kinin-Code-Offical merged 2 commits intomainfrom
issue-17-carinfo-contract-fix
Dec 22, 2025
Merged

issue 17 carinfo contract fix#25
Kinin-Code-Offical merged 2 commits intomainfrom
issue-17-carinfo-contract-fix

Conversation

@Kinin-Code-Offical
Copy link
Owner

@Kinin-Code-Offical Kinin-Code-Offical commented Dec 22, 2025

  • docs: add community standards and license
  • feat(backend): Fix CarInfo API contract mismatch (P0)

Summary by Sourcery

Align the CarInfo edit API response and identifier handling with the expected contract while introducing basic project governance and build updates.

New Features:

  • Allow updating car info records by either ID or assetID and return a structured success payload with affected row metadata.

Bug Fixes:

  • Correct the CarInfo edit endpoint contract to use a consistent JSON response envelope and appropriate HTTP status codes for authentication, validation, and server errors.

Enhancements:

  • Improve error messaging and internal validation in the CarInfo update logic, including field whitelisting and basic type handling.
  • Upgrade the GitHub release workflow to build with Java 17 instead of Java 11.

Build:

  • Update GitHub Actions release workflow to use Temurin JDK 17.

CI:

  • Adjust CI release pipeline configuration to target Java 17.

Documentation:

  • Add contributing guidelines, a project code of conduct, and standardized GitHub issue and pull request templates to document community standards and workflows.

Fixes #17

Implements a backward-compatible fix for the editcarinfo.php endpoint. The script now accepts either ID or �ssetID as the identifier for updates, prioritizing ID. This resolves the contract mismatch where the Flutter client was sending �ssetID while the backend expected the primary key ID. The endpoint now also uses prepared statements and returns a standardized JSON response.
Copilot AI review requested due to automatic review settings December 22, 2025 03:20
@sourcery-ai
Copy link

sourcery-ai bot commented Dec 22, 2025

Reviewer's Guide

Aligns the CarInfo edit backend endpoint with the expected API contract (ID or assetID, structured JSON, explicit HTTP status codes), tightens validation and error handling, updates the release workflow to Java 17, and introduces standard community and contribution documentation and GitHub templates.

Sequence diagram for updated CarInfo edit endpoint behavior

sequenceDiagram
    actor Client
    participant EditCarInfoAPI as editcarinfo_php
    participant DB as MySQL_carinfos

    Client->>EditCarInfoAPI: POST /backend/carinfos/editcarinfo.php
    activate EditCarInfoAPI

    EditCarInfoAPI->>EditCarInfoAPI: Validate phpPassword
    alt phpPassword invalid
        EditCarInfoAPI-->>Client: 401 Unauthorized\n{ success: false, message: "Invalid PHP password." }
    else phpPassword valid
        EditCarInfoAPI->>EditCarInfoAPI: Read ID and assetID
        alt missing ID and assetID
            EditCarInfoAPI-->>Client: 400 Bad Request\n{ success: false, message: "A required identifier (ID or assetID) is missing." }
        else identifier present
            EditCarInfoAPI->>EditCarInfoAPI: Collect allowedFields from POST
            alt no allowed fields provided
                EditCarInfoAPI-->>Client: 500 Internal Server Error\n{ success: false, message: "No fields to update were provided." }
            else fields to update
                EditCarInfoAPI->>EditCarInfoAPI: Build UPDATE SQL with WHERE ID or assetID
                EditCarInfoAPI->>DB: prepare(sql)
                alt prepare fails
                    DB-->>EditCarInfoAPI: error
                    EditCarInfoAPI-->>Client: 500 Internal Server Error\n{ success: false, message: "SQL statement preparation failed: ..." }
                else prepare ok
                    EditCarInfoAPI->>DB: bind_param(bindTypes, bindValues)
                    EditCarInfoAPI->>DB: execute()
                    alt execute fails
                        DB-->>EditCarInfoAPI: error
                        EditCarInfoAPI-->>Client: 500 Internal Server Error\n{ success: false, message: "SQL statement execution failed: ..." }
                    else execute ok
                        DB-->>EditCarInfoAPI: affected_rows
                        EditCarInfoAPI-->>Client: 200 OK\n{ success: true, message: "Car info updated successfully.", data: { affected_rows } }
                    end
                end
            end
        end
    end
    deactivate EditCarInfoAPI
Loading

File-Level Changes

Change Details Files
Refactor CarInfo edit endpoint to support ID or assetID, improve validation, and standardize JSON responses and HTTP status codes.
  • Preserve phpPassword-based auth while preparing for future JWT-based security and return 401 on invalid credentials.
  • Allow selecting the record to update by either ID or assetID with prioritized resolution and proper 400 error when neither is provided.
  • Restrict updates to a fixed allowlist of fields, converting numeric fields to integers, normalizing empty strings to null, and validating date format where applicable.
  • Refactor SQL update construction to build dynamic SET clauses, bind types/values arrays, and support both ID and assetID in the WHERE clause using prepared statements.
  • Change response payload to a structured JSON object with success flag, message string, and data.affected_rows, and map unhandled errors to HTTP 500 while preserving earlier explicit status codes.
backend/carinfos/editcarinfo.php
Update CI release workflow Java version.
  • Change GitHub Actions release workflow to use Temurin Java 17 instead of Java 11 for the build pipeline.
.github/workflows/release.yml
Add project governance docs and GitHub contribution templates.
  • Introduce CONTRIBUTING guidelines documenting workflow, branching, testing, and coding standards for Flutter and PHP.
  • Add a project Code of Conduct describing expected behavior, unacceptable conduct, and enforcement responsibilities.
  • Create GitHub issue templates for bug reports and feature requests to standardize incoming issues.
  • Add a pull request template to guide authors on description, testing, and checklist expectations.
  • Add an open-source LICENSE file to formalize project licensing.
CONTRIBUTING.md
CODE_OF_CONDUCT.md
.github/ISSUE_TEMPLATE/bug_report.md
.github/ISSUE_TEMPLATE/feature_request.md
.github/PULL_REQUEST_TEMPLATE.md
LICENSE

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 4 issues, and left some high level feedback:

  • The new editcarinfo endpoint dropped the seyruseferdate YYYY-MM-DD format validation that existed before; if clients or downstream code rely on this constraint, consider reintroducing a simple format check to avoid silently accepting invalid dates.
  • For the No fields to update were provided. case you currently return a 500 unless a code was set earlier; this appears to be a client error, so explicitly setting a 4xx status (e.g., 400) before throwing would make the API contract clearer and error handling more accurate.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new editcarinfo endpoint dropped the `seyruseferdate` `YYYY-MM-DD` format validation that existed before; if clients or downstream code rely on this constraint, consider reintroducing a simple format check to avoid silently accepting invalid dates.
- For the `No fields to update were provided.` case you currently return a 500 unless a code was set earlier; this appears to be a client error, so explicitly setting a 4xx status (e.g., 400) before throwing would make the API contract clearer and error handling more accurate.

## Individual Comments

### Comment 1
<location> `backend/carinfos/editcarinfo.php:36-41` </location>
<code_context>
+        throw new Exception('A required identifier (ID or assetID) is missing.');
+    }
+
+    $allowedFields = ['brand', 'sasino', 'engineno', 'enginepow', 'cartype', 'carusage', 'price', 'productionyear', 'seatcapacity', 'seyruseferdate'];
+    $setClauses = [];
+    $bindValues = [];
+    $bindTypes = '';
+
+    foreach ($allowedFields as $field) {
+        if (array_key_exists($field, $_POST)) {
+            $value = $_POST[$field];
</code_context>

<issue_to_address>
**issue (bug_risk):** The previous `seyruseferdate` format validation has been removed, which can allow invalid dates into the DB.

The new loop now treats `seyruseferdate` as a plain string and no longer enforces the `YYYY-MM-DD` format that was previously checked. If the DB or downstream logic assumes a valid date, this can introduce bad data and hard-to-track bugs. Please add a specific validation branch for `seyruseferdate` inside the loop to preserve the original guarantee.
</issue_to_address>

### Comment 2
<location> `backend/carinfos/editcarinfo.php:62-64` </location>
<code_context>
-    $sql = "UPDATE carinfos SET ".implode(', ',$set)." WHERE ID = ?";
-    $types.='i';
-    $vals[] = $id;
+    if (empty($setClauses)) {
+        throw new Exception('No fields to update were provided.');
+    }
+
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Client-side input issues like “no fields to update” currently end up as HTTP 500 instead of a 4xx.

Because we throw here without setting an HTTP status, this case will be returned as 500. Since this is a client error, please set an appropriate 4xx status (e.g. `http_response_code(400);`) before throwing, consistent with how missing identifiers are handled, so clients can distinguish bad requests from real server errors.

```suggestion
    if (empty($setClauses)) {
        http_response_code(400);
        throw new Exception('No fields to update were provided.');
    }
```
</issue_to_address>

### Comment 3
<location> `backend/carinfos/editcarinfo.php:89-94` </location>
<code_context>
-    $resp['success']=false;
-    $resp['message']=$e->getMessage();
+
+} catch (Exception $e) {
+    if (http_response_code() === 200) { // If no HTTP code was set by us, it's an internal error
+        http_response_code(500);
+    }
+    $response['success'] = false;
+    $response['message'] = $e->getMessage();
 }
-echo json_encode($resp,JSON_UNESCAPED_UNICODE);
</code_context>

<issue_to_address>
**🚨 issue (security):** Returning raw exception messages in the API response may leak internal details and SQL errors.

Some exceptions here include low-level messages like `SQL statement preparation failed: ...` or `SQL statement execution failed: ...`. Sending `$e->getMessage()` directly to clients can expose internal DB details. Instead, map exceptions to generic user-facing messages (e.g. "Internal server error") and log the detailed message server-side, only returning specific messages when they are known-safe (such as validation errors).
</issue_to_address>

### Comment 4
<location> `CODE_OF_CONDUCT.md:5` </location>
<code_context>
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
</code_context>

<issue_to_address>
**issue (typo):** Fix the phrasing "pledge to making" to the grammatically correct "pledge to make".

Change `pledge to making participation` to `pledge to make participation` for correct grammar and smoother reading.

```suggestion
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +36 to +41
$allowedFields = ['brand', 'sasino', 'engineno', 'enginepow', 'cartype', 'carusage', 'price', 'productionyear', 'seatcapacity', 'seyruseferdate'];
$setClauses = [];
$bindValues = [];
$bindTypes = '';

foreach ($allowedFields as $field) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): The previous seyruseferdate format validation has been removed, which can allow invalid dates into the DB.

The new loop now treats seyruseferdate as a plain string and no longer enforces the YYYY-MM-DD format that was previously checked. If the DB or downstream logic assumes a valid date, this can introduce bad data and hard-to-track bugs. Please add a specific validation branch for seyruseferdate inside the loop to preserve the original guarantee.

Comment on lines +62 to +64
if (empty($setClauses)) {
throw new Exception('No fields to update were provided.');
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Client-side input issues like “no fields to update” currently end up as HTTP 500 instead of a 4xx.

Because we throw here without setting an HTTP status, this case will be returned as 500. Since this is a client error, please set an appropriate 4xx status (e.g. http_response_code(400);) before throwing, consistent with how missing identifiers are handled, so clients can distinguish bad requests from real server errors.

Suggested change
if (empty($setClauses)) {
throw new Exception('No fields to update were provided.');
}
if (empty($setClauses)) {
http_response_code(400);
throw new Exception('No fields to update were provided.');
}

Comment on lines +89 to +94
} catch (Exception $e) {
if (http_response_code() === 200) { // If no HTTP code was set by us, it's an internal error
http_response_code(500);
}
$response['success'] = false;
$response['message'] = $e->getMessage();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 issue (security): Returning raw exception messages in the API response may leak internal details and SQL errors.

Some exceptions here include low-level messages like SQL statement preparation failed: ... or SQL statement execution failed: .... Sending $e->getMessage() directly to clients can expose internal DB details. Instead, map exceptions to generic user-facing messages (e.g. "Internal server error") and log the detailed message server-side, only returning specific messages when they are known-safe (such as validation errors).


## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (typo): Fix the phrasing "pledge to making" to the grammatically correct "pledge to make".

Change pledge to making participation to pledge to make participation for correct grammar and smoother reading.

Suggested change
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a high-priority API contract mismatch in the CarInfo edit endpoint and adds essential community documentation. The backend changes modernize the response structure and improve error handling, while the documentation additions establish project standards for contributors.

Key Changes:

  • Refactored editcarinfo.php to support both ID and assetID for updates, with standardized response structure including a data wrapper
  • Added MIT License and community standards (Contributing guide, Code of Conduct)
  • Updated Java version from 11 to 17 in GitHub Actions workflow

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
backend/carinfos/editcarinfo.php Refactored to support ID/assetID-based updates with improved error handling and standardized API response structure
LICENSE Added MIT License with 2025 copyright for SigortaCu Contributors
CONTRIBUTING.md Added contribution guidelines including code style standards (Flutter style guide, PSR-12 for PHP)
CODE_OF_CONDUCT.md Added code of conduct defining community standards and behavior expectations
.github/workflows/release.yml Updated Java version from 11 to 17 for compatibility with modern Flutter/Android builds
.github/PULL_REQUEST_TEMPLATE.md Added PR template with standard sections for description, type of change, testing, and checklist
.github/ISSUE_TEMPLATE/feature_request.md Added feature request template for structured enhancement proposals
.github/ISSUE_TEMPLATE/bug_report.md Added bug report template for consistent issue reporting

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +41 to 59
foreach ($allowedFields as $field) {
if (array_key_exists($field, $_POST)) {
$value = $_POST[$field];

// Basic validation and type setting
$isNumericField = in_array($field, ['enginepow', 'price', 'productionyear', 'seatcapacity']);
if ($isNumericField && $value !== '') {
$value = intval($value);
$bindTypes .= 'i';
} else {
$types.='s';
$bindTypes .= 's';
}
if($val==='') $val=null; // boş ise null kaydet
$set[] = "$f = ?";
$vals[] = $val;

// Set empty strings to null for the database
if ($value === '') $value = null;

$setClauses[] = "$field = ?";
$bindValues[] = $value;
}
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing date format validation for the 'seyruseferdate' field. The original code validated that this field matches the YYYY-MM-DD format when provided. This validation has been removed, which could allow invalid date formats to be inserted into the database.

Other carinfo endpoints (addcarinfo.php and addfullcarinfo.php) include this validation. For consistency and data integrity, you should add the validation back before processing the field.

Copilot uses AI. Check for mistakes.
Comment on lines +74 to +94
throw new Exception('SQL statement preparation failed: ' . $connNow->error);
}

$stmt->bind_param($types, ...$vals);
if(!$stmt->execute()) throw new Exception('Execute hatası: '.$stmt->error);
$stmt->bind_param($bindTypes, ...$bindValues);

if (!$stmt->execute()) {
throw new Exception('SQL statement execution failed: ' . $stmt->error);
}

$resp['success']=true;
$resp['message']='Araç güncellendi';
$resp['affected']=$stmt->affected_rows;
$response['success'] = true;
$response['message'] = 'Car info updated successfully.';
$response['data'] = ['affected_rows' => $stmt->affected_rows];

$stmt->close();
} catch(Exception $e){
$resp['success']=false;
$resp['message']=$e->getMessage();

} catch (Exception $e) {
if (http_response_code() === 200) { // If no HTTP code was set by us, it's an internal error
http_response_code(500);
}
$response['success'] = false;
$response['message'] = $e->getMessage();
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code concatenates $connNow->error and $stmt->error into exception messages that are then returned directly to clients via $response['message'], which can leak internal database details and query structure. An attacker can deliberately trigger SQL errors (for example by sending malformed or out-of-range input) to enumerate schema information and error states useful for further attacks. Instead, log detailed database errors only on the server and return a generic error message to the client while preserving appropriate HTTP status codes.

Copilot uses AI. Check for mistakes.
@Kinin-Code-Offical Kinin-Code-Offical merged commit 6d56d28 into main Dec 22, 2025
10 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants