인셔셔RSS 관심 있는 블로그, 뉴스, 기술 정보를 효율적으로 추적하고 읽으세요
원문 읽기 InertiaRSS에서 열기

추천 피드

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
D365 F&O에서의 지휘체계: 세 가지 생산 함정
SapotaCorp · 2026-05-24 · via DEV Community

명령 체인이 F(&O) 커스터마이징의 기본 패턴이 되었습니다. 오버레이 접근 방식은 지속할 수 없었기 때문입니다. 매번 One Version 업데이트가 무언가를 깨뜨리고 파트너들은 설계상 앞으로 호환되어야 할 커스터마이징을 수리하기 위해 업그레이드 예산을 썼습니다. CoC는 확장 프로그램이 next()을 사용하여 기본 메서드를 래핑하고 전적으로 오버레이 춤을 건너뛸 수 있게 합니다.

작동 원리를 읽는 데 한 분이 걸립니다. 생산 중에 자주 발생하여 기록해야 할 세 가지 오류 모드가 나타납니다.

함정 1: next()를 증가시킬 때 깜빡함

CoC에 새로운 팀은 종종 다음과 같은 검증 확장을 작성합니다:

[ExtensionOf(tableStr(SalesTable))]
final class SalesTableExt_Extension
{
    public boolean validateWrite()
    {
        if (this.CustomCheck == NoYes::No)
        {
            return checkFailed("Custom check failed");
        }
        return true;
    }
}

전체 화면 모드로 전환 전체 화면 모드 종료

오류: 없음next validateWrite() 호출. 기본 메서드는 실행되지 않으므로 모든 재고 검증이 조용히 사라짐. 오직 커스텀-체크 경로만 실행되는 단위 테스트는 통과됨. 빠진 기본 검증은 기본이 거부했을 테 데이터가 생산 환경으로 통과하면 나타나지 않음.

로직을 추가하는 것이 아니라 대체하는 것이 목적이라면, 먼저 next()를 호출하고 결과를 결합하라:

public boolean validateWrite()
{
    boolean ret = next validateWrite();
    if (ret && this.CustomCheck == NoYes::No)
    {
        ret = checkFailed("Custom check failed");
    }
    return ret;
}

전체 화면 모드를 입력하십시오 전체 화면 모드 종료

next()을 건너뛰는 것은 때때로 합법적일 수 있지만, 의도적이어야 하며, 주석을 달고 검토되어야 합니다. 의도치 않은 건너뛰기는 침묵하는 데이터 무결성 버그가 살아있는 곳입니다.

함정 2: 잘못된 생애주기 핸들 선택

FormDataSource.init()은 기록이 로드되기 전에 실행됩니다. 익스텐션 코드가 읽는 것은this.cursor() 또는 기록 컨텍스트를 가정하면 예외가 발생하거나 예측 불가능하게 동작합니다. 동적 필터를 배포하는 팀들은 로직을 init()에 넣곤 하는데, 그 이유는 그것이 첫 번째 훅(hook)을 보는 것부터이기 때문입니다. 그런 다음 사용자가 비어 있는 데이터셋을 가진 경우에 폼을 열 때 처음으로 크래시가 발생합니다.

폼 수준의 생명주기 훅(lifecycle hook)은 각각 목적이 있습니다.

  • init() - 폼 수준 설정, 아직 데이터 없음
  • executeQuery() - 쿼리가 구축된 후, fetch 전
  • active() - 데이터 소스에 기록이 활성화된 후
  • 이벤트 전/후 처리기(executeQuery) - 기본을 재정의하지 않고 쿼리를 변형하는 가장 깨끗한 방법

파라미터 테이블에서 동적 필터링을 위해, executeQuery의 이벤트 전 처리기는 이벤트 인수를 통해 사용할 수 있는 데이터 컨텍스트를 이용해 쿼리의 범위를 수정할 수 있습니다. crash 없이, 기본 메서드 재정의 없이, 무뎌진 하위 연결 없이.

3번 함정: private 또는 protected 멤버에 접근하려고 함

CoC 확장은 기본 클래스의 private 또는 protected 멤버에 접근할 수 없습니다. 오버레이 시대의 F&O로 이전하는 개발자들은 첫 번째로 이 문제를 마주합니다:

[ExtensionOf(classStr(SalesLineType))]
final class SalesLineTypeExt_Extension
{
    public boolean checkPrice()
    {
        // Compile error: _commonPricing is protected
        return this._commonPricing.checkMyThing();
    }
}

전체 화면 모드 입력 전체 화면 모드 종료

Microsoft의 확장 프레임워크 문서에는 네 가지 옵션이 설명되어 있습니다.

  1. 호킹 가능한 기본 메서드 - 개인적인 행동이 공개 메서드를 통해 노출될 경우, 그 메서드를 호출하세요.
  2. 형제 클래스 접근 - 가끔 공개 클래스가 필요한 것을 충분히 노출할 수 있습니다.
  3. 데이터를 인수를 통해 노출하는 메서드의 이벤트 핸들러 - 가장 깨끗한 경로입니다.
  4. LCS 이슈 검색을 통해 접근 요청 - Microsoft는 여러 버전 릴리스에 따른 파트너 요청에 응해 많은 회원을 개설했습니다.

반성을 찾으려는 것은 잘못된 답변입니다. 다음 컴파일이 멤버 레이아웃을 변경할 때까지는 작동하지만, 다시 오버레이 수준의 취약성으로 돌아옵니다.

침묵하는 확장을 디버깅합니다

가장 짜증 나는 CoC 실패는 컴파일되고 배포되지만 실행 시 아무것도 하지 않는 확장입니다. 작동하는 F&O 코드베이스의 리뷰에서 나타나는 근본 원인:

  • [ExtensionOf] 속성이 잘못된 대상을 가리킨다 - formStr() / tableStr() / classStr()에 타이포가 있습니다.
  • 확장 클래스는 final - CoC에 필요합니다.
  • 메서드 서명이 정확히 일치하지 않습니다 - 매개변수 유형 불일치는 조용히 건너뜁니다.
  • 확장을 포함하는 모델이 대상 환경의 모델 목록에 없습니다.

첫 번째 진단 단계: 메서드 맨 위에 info("hit")를 드롭하고, 재컴파일하고, 시나리오를 실행하고, Infolog를 확인합니다. 아무것도 나타나지 않으면 하나 이상의 위 사항이 잘못되었습니다.

코드 리뷰는 보험입니다

건강한 F & O 코드베이스를 사용하는 팀은 CoC 확장에 대해 PR 시간 체크리스트를 사용합니다: next()가 올바르게 호출되었는지, 적절한 생명주기 훅이 선택되었는지, 개인 멤버 접근 시도가 없는지, SysTest를 통해 단위 테스트 커버리지가 있는지 확인합니다. PR당 15분은 한 버전 업데이트가 주말 장애로 변하지 않도록 보험 정책처럼 작동합니다.